将语法转换为>> =语法的简单示例

时间:2014-04-07 10:04:10

标签: haskell

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及其有价值的答案。

3 个答案:

答案 0 :(得分: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的一步转换,您将获得

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

从语法上讲,lambda表达式的括号可以省略,但是在这里明确地写它们有助于澄清并明确这些函数的嵌套结构,特别是如果我们排列缩进。

完整翻译安排monad的fail函数在模式不匹配时被调用,但由于变量模式(line1line2)是无可辩驳的,因此这个翻译是事实上确切。

答案 1 :(得分:4)

类型x <- m的语句可以翻译为m >>= \x -> ...,而返回值不像m那样绑定的语句可以翻译为m >> ...

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

翻译不准确 - fail monad函数使事情变得复杂。您可以阅读here,但据我所知,在处理IO monad时无关紧要。

答案 2 :(得分:1)

以下是Will仅使用>>=

的非常好的答案的代码
reverse2lines' :: IO () 
reverse2lines' = 
    getLine >>= (\line1 -> 
        getLine >>= (\line2 -> 
            putStrLn (reverse line2) >>= (\_ ->
               putStrLn (reverse line1) )))

获得的经验教训:do中的排序只对应于lambda表达式的嵌套。