将符号转换为绑定表示法

时间:2018-04-21 20:51:37

标签: haskell monads

如何将下面的Haskell表示法转换为绑定(>>=)表示法?

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

我是一名具有良好知识的Haskell初学者,我尝试了类似

的东西
getLine >>= (\line1 -> getLine >>= (\line2 -> putStrLn $ reverse(line2)))

但我无法在另一行(即line1)中包含print语句。请帮助我正确理解这个概念。

3 个答案:

答案 0 :(得分:9)

你几乎就在那里:你需要使用>>

getLine >>= (\line1 -> 
getLine >>= (\line2 -> 
putStrLn (reverse line2) >>
putStrLn (reverse line1)
))

请注意,>> ...相当于>>= (\_ -> ...),因此如果您愿意,也可以使用它。

同样,你的块

 do line1 <- getLine
    line2 <- getLine
    putStrLn (reverse line2)
    putStrLn (reverse line1)

相当于

 do line1 <- getLine
    line2 <- getLine
    _ <- putStrLn (reverse line2)
    putStrLn (reverse line1)

基本上,没有明确<-的块(但最后一个)中的任何条目都使用>>(或者,如果您愿意,前面有一个隐式_ <-)。

答案 1 :(得分:6)

假设你的意思

rev2lines = do
           line1 <- getLine
           line2 <- getLine
           putStrLn (reverse line2)
           putStrLn (reverse line1)
脱口看起来像

rev2lines =
           getLine >>= \line1 ->
           getLine >>= \line2 ->
           putStrLn (reverse line2) >>
           putStrLn (reverse line1)

解析为

rev2lines =
    getLine >>= (
        \line1 -> getLine >>= (
            \line2 -> (putStrLn (reverse line2)) >> (putStrLn (reverse line1))))

答案 2 :(得分:6)

putStrLn的类型为IO (),因此我们可以构建一个虚拟变量_,以获取单位类型 ()和所以继续处理,所以:

rev2lines = getLine >>=
                (\line1 -> getLine >>=
                    (\line2 -> putStrLn (reverse line2) >>=
                        (\_ -> putStrLn (reverse line1))
                    )
                )

由于模式f >>= \_ -> g经常发生,因此(>>) :: Monad m => m a -> m b -> m b运算符使f >> g在语义上与f >>= (\_ -> g)相同,因此较短的形式为:

rev2lines = getLine >>=
                (\line1 -> getLine >>=
                    (\line2 -> putStrLn (reverse line2) >>
                        (putStrLn (reverse line1))
                    )
                )