Reputation: 769
How do I convert the below Haskell do notation to the bind (>>=)
notation?
rev2lines :: IO ()
rev2lines = do line1 <- getLine
line2 <- getLine
putStrLn (reverse line2)
putStrLn (reverse line1)
I am a Haskell beginner with decent knowledge and I tried something like
getLine >>= (\line1 -> getLine >>= (\line2 -> putStrLn $ reverse(line2)))
but I am not able to include the print statement for the other line i.e. line1. Kindly help me to understand this concept properly.
Upvotes: 10
Views: 814
Reputation: 477533
The putStrLn
has type IO ()
, so we can construct a dummy variable _
as a way to obtain the unit type ()
and so keep processing, so:
rev2lines = getLine >>=
(\line1 -> getLine >>=
(\line2 -> putStrLn (reverse line2) >>=
(\_ -> putStrLn (reverse line1))
)
)
Since the pattern f >>= \_ -> g
occurs quite often, there is the (>>) :: Monad m => m a -> m b -> m b
operator such that f >> g
is semantically the same as f >>= (\_ -> g)
, so a shorter form is:
rev2lines = getLine >>=
(\line1 -> getLine >>=
(\line2 -> putStrLn (reverse line2) >>
(putStrLn (reverse line1))
)
)
Upvotes: 6
Reputation: 85877
Assuming you meant
rev2lines = do
line1 <- getLine
line2 <- getLine
putStrLn (reverse line2)
putStrLn (reverse line1)
the desugaring looks like
rev2lines =
getLine >>= \line1 ->
getLine >>= \line2 ->
putStrLn (reverse line2) >>
putStrLn (reverse line1)
which parses as
rev2lines =
getLine >>= (
\line1 -> getLine >>= (
\line2 -> (putStrLn (reverse line2)) >> (putStrLn (reverse line1))))
Upvotes: 7
Reputation: 116174
You're almost there: you need to use >>
.
getLine >>= (\line1 ->
getLine >>= (\line2 ->
putStrLn (reverse line2) >>
putStrLn (reverse line1)
))
Note that >> ...
is equivalent to >>= (\_ -> ...)
, so you can also use that if you prefer.
Similarly, your block
do line1 <- getLine
line2 <- getLine
putStrLn (reverse line2)
putStrLn (reverse line1)
is equivalent to
do line1 <- getLine
line2 <- getLine
_ <- putStrLn (reverse line2)
putStrLn (reverse line1)
Essentially, any entry in the block (but the last one) which has no explicit <-
uses >>
(or, if you prefer, has an implicit _ <-
in front).
Upvotes: 11