'do'结构中的最后一个语句必须是表达式Haskell

use*_*603 5 haskell

基于其他类似的问题,我发现我认为我的问题与缩进有关,但我已经搞砸了很多但仍然无法弄明白.

addBook = do
    putStrLn "Enter the title of the Book"
    tit <- getLine
    putStrLn "Enter the author of "++tit
    aut <- getLine
    putStrLn "Enter the year "++tit++" was published"
    yr <- getLine
Run Code Online (Sandbox Code Playgroud)

gee*_*aur 18

在你的情况下,它不是缩进; 你真的用一些不是表达的东西完成了你的功能. yr <- getLine- 在此之后你期望发生什么yr,或者aut就此而言?他们只是晃来晃去,没用.

可以更清楚地说明这是如何转换的:

addBook = putStrLn "Enter the title of the Book" >>
          getLine >>= \tit ->
          putStrLn "Enter the author of "++ tit >>
          getLine >>= \aut ->
          putStrLn "Enter the year "++tit++" was published" >>
          getLine >>= \yr ->
Run Code Online (Sandbox Code Playgroud)

那么,你想在最后一箭之后得到什么?


ick*_*fay 7

想想的类型addBook.它在IO a哪里a......什么都没有.这不起作用.你的monad必须有一些结果.

你可能想在最后添加这样的东西:

return (tit, aut, yr)
Run Code Online (Sandbox Code Playgroud)

或者,如果您不想获得任何有用的结果,请返回一个空元组(单位):

return ()
Run Code Online (Sandbox Code Playgroud)

  • @ user1319603:请注意,`return`与命令式语言中的对应物不同.在Haskell中,`return`就像其他任何函数一样.它采用某种类型的`a`的值并将其包含在(在这种情况下)类型为"IO a"的值中.在你了解monad之前,最好使用这个经验法则:`do`块中的最后一个东西必须为某个类型`a`设置类型`IO a`.在你的情况下,`yr < - getLine`将具有类型`String`并且不允许(实际上,具有类型`IO a→a`的函数打破了许多不错的属性). (5认同)