2012-04-07 64 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

相關問題