2012-04-07 28 views
5

Dựa trên các câu hỏi tương tự khác mà tôi thấy mình thấy vấn đề của mình liên quan đến thụt đầu dòng, nhưng tôi đã làm điều đó rất nhiều và vẫn không thể hiểu được ngoài.Câu lệnh cuối cùng trong một cấu trúc 'do' phải là một biểu thức 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

điều này có thể liên quan đến những người khác ... Tôi có dòng đầu tiên trong "làm" với một thụt lề tab và phần còn lại có dấu cách: P –

Trả lời

18

Trong trường hợp của bạn, nó không thụt lề; bạn thực sự đã hoàn thành chức năng của bạn với một cái gì đó không phải là một biểu thức. yr <- getLine - bạn mong đợi điều gì xảy ra với yr, hoặc cho rằng vấn đề aut, sau này? Họ chỉ lúng túng, không sử dụng.

Nó có thể rõ ràng hơn để chỉ ra cách để dịch:

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

Vì vậy, những gì đã làm bạn muốn có sau đó mũi tên cuối cùng?

+1

Ngoài ra, bạn có thể muốn đề cập đến rằng 'getLine' có thể được gọi mà không có kết quả của nó bị ràng buộc, ngay cả khi đó có lẽ không phải là những gì ông dự định. Anh ta có thể bị ấn tượng sai lầm rằng những thứ có kiểu trả về khác với '()' phải được ràng buộc với một biến. –

7

Hãy suy nghĩ về loại addBook. Đó là IO a nơi a là ... không có gì. Điều đó không hiệu quả. Monad của bạn phải có một số kết quả.

Bạn có thể muốn thêm một cái gì đó như thế này ở cuối:

return (tit, aut, yr) 

Ngoài ra, nếu bạn không muốn có bất kỳ kết quả hữu ích, trả về một tuple trống (một đơn vị):

return() 
+0

awsome! Hơn bạn rất nhiều! – user1319603

+5

@ user1319603: Tâm trí bạn, 'return' không giống như các đối tác của nó trong ngôn ngữ mệnh lệnh. Trong Haskell, 'return' có chức năng giống như bất kỳ hàm nào khác. Nó lấy một giá trị của một số kiểu 'a' và kết thúc nó vào (trong trường hợp này) giá trị của kiểu' IO a'. Trước khi bạn tìm hiểu về monads, cách tốt nhất là sử dụng quy tắc này: điều cuối cùng trong khối 'do' phải có kiểu' IO a' đối với một số loại 'a'. Trong trường hợp của bạn, 'yr <- getLine' sẽ có kiểu' String' và không được cho phép (thực sự, có hàm của kiểu 'IO a → a' ngắt nhiều thuộc tính tốt đẹp). – Vitus

+1

@ user1319603 Bạn nên * upvote * (nhấp vào mũi tên lên cho) mọi câu trả lời giúp bạn và * chấp nhận * (nhấp vào dấu kiểm) cho câu trả lời tốt nhất hoặc giúp bạn nhiều nhất. – dave4420

0

xóa dòng cuối cùng vì nó không phải là một biểu thức, sau đó sử dụng dấu ngoặc đơn cho các chuỗi bạn chuyển tới putStrLn.

1

Nếu bạn lấy mã của bạn:

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 

và "dịch" nó thành "bình thường" (phi do) ký hiệu (cho p = putStrLn "..."):

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

Bạn đang kết thúc với (yr -> điều đó không có ý nghĩa. Nếu bạn không có bất cứ thứ gì hữu ích để làm, bạn chỉ có thể trả về một tuple trống:

return() 

ở cuối:

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

Bạn có lẽ nên tự hỏi mình tại sao bạn cần để có được autyr.

+0

+1 cho dấu ngoặc đơn rõ ràng !!! ... có lẽ 'return (tit, aut, yr)' cũng thích hợp ... Ngoài ra, thay vì 'yr <- getLine; return() 'chúng ta chỉ có thể viết' getLine' - chúng ta chọn tùy thuộc vào cái chúng ta muốn "trả về". –

Các vấn đề liên quan