2012-04-07 68 views
5

基于我发现的其他类似问题,我认为我的问题与缩进有关,但我已经搞砸了很多,但仍然无法确定它出。'do'构造中的最后一个语句必须是一个表达式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 
+0

这可能与其他人有关......我在“do”的第一行用制表符缩进,其余用空格:P – 2012-05-25 05:14:02

回答

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 -> 

那么,你想有以下这最后一箭什么?

+1

另外,你可能想提一下'getLine'可以被调用,而不会导致绑定的结果,即使这可能不是他想要的。他可能错误地认为具有除(')之外的返回类型的东西必须绑定到一个变量。 – 2012-04-08 18:09:21

7

想想addBook的类型。这是IO a其中a是......什么都没有。这是行不通的。你的monad必须有一些结果。

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

return (tit, aut, yr) 

另外,如果你不希望有任何有用的结果,返回一个空的元组(单位):

return() 
+0

awsome!比你多! – user1319603 2012-04-07 21:11:41

+5

@ user1319603:介意你,'return'与命令式语言中的同行不同。在Haskell中,'return'和其他任何函数一样。它取得某种类型为'a'的值,并将其封装到(在这种情况下)类型为'IO a'的值中。在你了解monads之前,最好使用这个经验法则:'do'块中的最后一项必须为'a'类型'IO a'类型。在你的情况下,'yr < - getLine'将会有'String'类型,这是不允许的(事实上,具有'IO a→a'类型的函数会破坏很多很好的属性)。 – Vitus 2012-04-07 22:16:31

+1

@ user1319603你应该* * * *(点击向上箭头)每一个帮助你的答案,*接受*(点击复选标记)答案是最好的或最有帮助的答案。 – dave4420 2012-04-08 00:13:05

0

删除最后一行,因为它不是表达式, 然后对传递给putStrLn的字符串使用括号。

1

如果你把你的代码:您与(yr ->结束了

addBook = 
    p >> getLine >>= (\tit -> 
     p >> getLine >>= (\aut -> 
      p >> getLine >>= (yr -> 

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 

和 “翻译” 为 “正常”(非do)符号(给出p = putStrLn "...")这没有意义。如果你没有别的有用的事,你可以返回一个空的元组:

return() 

末:

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 
    return() 

你或许应该问自己,为什么你需要得到autyr虽然。

+0

+1为明确的括号! ...也许'返回(tit,aut,yr)'也是合适的......此外,而不是'yr < - getLine; return()'我们可以写'getLine' - 我们根据我们想要“返回”来选择它。 – 2014-06-11 19:06:40

相关问题