2014-04-07 85 views
1

如何將reverse2lines轉換爲使用>>=語法?就像addOneInt轉化爲addOneInt'將語法轉換爲>> =語法的簡單示例

addOneInt :: IO() 
addOneInt = do line <- getLine 
       putStrLn (show (1 + read line :: Int))  


addOneInt' :: IO() 
addOneInt' = getLine >>= \line -> 
      putStrLn (show (1 + read line :: Int)) 

reverse2lines :: IO() 
reverse2lines = 
do line1 <- getLine 
    line2 <- getLine 
    putStrLn (reverse line2) 
    putStrLn (reverse line1) 

請考慮閱讀後續的question及其有價值的答案。 x <- m類型的

回答

5

你可以從你已經知道的東西中安全地推導出它。通過充分的圓括號您addOneInt'開始:

addOneInt' = getLine >>= (\line -> 
      putStrLn (show (1 + read line :: Int))) 

接下來,您reverse2lines可以等效根據需要,你寫成

reverse2lines = 
do { line1 <- getLine ; 
     do { line2 <- getLine ; 
      do { putStrLn (reverse line2) ; 
       do { putStrLn (reverse line1) } } } } 

應用,你已經使用addOneInt一步法轉化,儘可能多的時間'd得到

reverse2lines' :: IO() 
reverse2lines' = 
    getLine >>= (\line1 -> 
     getLine >>= (\line2 -> 
     putStrLn (reverse line2) >> 
      putStrLn (reverse line1))) 

在句法上,可以省略lambda表達式的括號,但是寫入它們明確地說,這有助於澄清和明確這些函數的嵌套結構,特別是如果我們要排列縮進。

全文翻譯安排上的不匹配模式被稱爲單子的fail功能,但由於變量模式(line1line2)是無可辯駁的,這個翻譯其實確切。

+0

謝謝你的詳細答案,是否有可能用'>> ='來制定'reverse2lines'?沒有'>>'? – jhegedus

+2

是,'m >> n === m >> =(\ _ - > n)'。對於一些單子,它甚至可以這樣定義;對於其他人來說,更有效的特定代碼可能用於'>>'。 –

+0

謝謝,我試着重寫它,它會是一個很好的練習。 – jhegedus

4

語句可譯爲m >>= \x -> ...,並且其中所述返回值未綁定像m語句可以翻譯爲m >> ...

reverse2lines :: IO() 
reverse2lines = getLine 
       >>= \line1 -> getLine 
       >>= \line2 -> putStrLn (reverse line2) 
       >> putStrLn (reverse line1) 

翻譯不準確 - 的fail單子功能有點複雜的事情。你可以閱讀關於它here,但據我所知在處理IO monad時無關緊要。

1

這裏只有>>=利用威爾的非常漂亮的答案代碼:

reverse2lines' :: IO() 
reverse2lines' = 
    getLine >>= (\line1 -> 
     getLine >>= (\line2 -> 
      putStrLn (reverse line2) >>= (\_ -> 
       putStrLn (reverse line1)))) 

教訓:在do測序簡單地對應lambda表達式的嵌套。