如何使用带有IO读取Int的绑定重写`do`块?

Ard*_*101 0 io monads haskell function do-notation

所以,我想prog使用>>/ >>=bindings而不是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)
Run Code Online (Sandbox Code Playgroud)

重写更简单的功能对我来说不是问题,但是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."
Run Code Online (Sandbox Code Playgroud)

然而,这只是不起作用,因为绑定readLn :: IO到下一个匿名函数存在问题\age.有帮助吗?

chi*_*chi 6

您正在更改代码,例如IntIO Int错误的位置删除和插入lambdas.

这样的事情应该有效:

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)
Run Code Online (Sandbox Code Playgroud)


Wil*_*ess 5

您可以让类型推断为您工作,

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 )
Run Code Online (Sandbox Code Playgroud)

既然你已经指定了prog :: IO Int,那就意味着return agedays :: IO Int,和agedays :: Int.

然后,两个操作数要*age * 365必须是同类型的,具体而言,是的agedays,因为我们有agedays = age * 365在那里.因此,它age :: Int已经如此.