如何将下面的Haskell符号转换为绑定(>>=)表示法?
rev2lines :: IO ()
rev2lines = do line1 <- getLine
line2 <- getLine
putStrLn (reverse line2)
putStrLn (reverse line1)
Run Code Online (Sandbox Code Playgroud)
我是一名具有良好知识的Haskell初学者,我尝试过类似的东西
getLine >>= (\line1 -> getLine >>= (\line2 -> putStrLn $ reverse(line2)))
Run Code Online (Sandbox Code Playgroud)
但是我无法在另一行(即line1)中包含print语句.请帮助我正确理解这个概念.
你几乎就在那里:你需要使用>>.
getLine >>= (\line1 ->
getLine >>= (\line2 ->
putStrLn (reverse line2) >>
putStrLn (reverse line1)
))
Run Code Online (Sandbox Code Playgroud)
请注意,这>> ...相当于>>= (\_ -> ...),如果您愿意,也可以使用它.
同样,你的块
do line1 <- getLine
line2 <- getLine
putStrLn (reverse line2)
putStrLn (reverse line1)
Run Code Online (Sandbox Code Playgroud)
相当于
do line1 <- getLine
line2 <- getLine
_ <- putStrLn (reverse line2)
putStrLn (reverse line1)
Run Code Online (Sandbox Code Playgroud)
本质上,块中的任何条目(但最后一个条目)没有明确的<-用途>>(或者,如果您愿意,_ <-前面有一个隐含的条目).
假设你的意思
rev2lines = do
line1 <- getLine
line2 <- getLine
putStrLn (reverse line2)
putStrLn (reverse line1)
Run Code Online (Sandbox Code Playgroud)
看起来很糟糕
rev2lines =
getLine >>= \line1 ->
getLine >>= \line2 ->
putStrLn (reverse line2) >>
putStrLn (reverse line1)
Run Code Online (Sandbox Code Playgroud)
解析为
rev2lines =
getLine >>= (
\line1 -> getLine >>= (
\line2 -> (putStrLn (reverse line2)) >> (putStrLn (reverse line1))))
Run Code Online (Sandbox Code Playgroud)
的putStrLn具有类型IO (),因此,我们可以构建一个虚拟变量_,以此来获得所述单元类型 ()等保持处理,从而:
rev2lines = getLine >>=
(\line1 -> getLine >>=
(\line2 -> putStrLn (reverse line2) >>=
(\_ -> putStrLn (reverse line1))
)
)
Run Code Online (Sandbox Code Playgroud)
由于模式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))
)
)
Run Code Online (Sandbox Code Playgroud)