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

How to rewrite `do` block using bind with an IO read Int?

所以,我想使用 >>/>>= 绑定而不是 do<- 来重写给定的 prog 函数:

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 时出现问题。有帮助吗?

您对代码的更改过多,例如从 IO Int 中删除 Int,并在错误的位置插入 lambda。

像这样的东西应该可以工作:

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)

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

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 已经。