Как переписать блок `do`, используя связывание с IO read Int? - PullRequest
0 голосов
/ 26 февраля 2019

Итак, я хочу переписать данную функцию prog, используя >> / >>= привязок вместо do и <-:

prog :: IO Int
     prog =
       do putStrLn "Hello there! How old are you?"
       age <- (readLn :: IO Int)
       let agedays = show $ age * 365
       putStrLn $ "So you are at least than " ++ agedays ++ " days old."
       return (read agedays)

Переписывать более простые функции непроблема для меня, но readLn :: IO Int вызывает у меня головную боль ...

Мое предложение было:

prog :: IO Int
prog =
     putStrLn "Hello there!How old are you?" >>
     readLn::IO >>=
     let agedays = \age -> show $ age * 365 >>
     putStrLn $ "So you are at least than " ++ agedays ++ " days old."

Однако это просто не работает, так как есть проблема спривязка readLn :: IO к следующей анонимной функции \age.Любая помощь?

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Вы можете позволить вывод типа сделать всю работу за вас,

prog :: IO Int
prog =
     putStrLn "Hello there! How old are you?" >>
     readLn >>= (\ age ->
     let agedays = age * 365 in
       putStrLn ("So you are at least " ++ show agedays ++ " days old.") >>
       return agedays )

Поскольку вы уже указали prog :: IO Int, это означает return agedays :: IO Int и agedays :: Int.

Тогда оба операнда * в age * 365 должны быть одного типа, в частности, типа agedays, поскольку у нас там agedays = age * 365.Таким образом, отсюда следует, что age :: Int уже.

0 голосов
/ 26 февраля 2019

Вы слишком сильно меняете код, например, удаляете Int из IO Int и вставляете лямбды в неправильные точки.

Примерно так должно работать:

prog =
   putStrLn "Hello there! How old are you?" >>
   (readLn :: IO Int) >>= \age ->
   let agedays = show $ age * 365
   in putStrLn $ "So you are at least than " ++ agedays ++ " days old." >>
   return (read agedays)
...