如何将下面的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语句。请帮助我正确理解这个概念。
答案 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))
)
)