How do I write the following function without using the "do" notation?
wordsCount = do
putStr "Write a line and press [enter]:\n"
s <- getLine
putStr $ show $ length . words $ s
putChar '\n'
Instead of using do
, you can use >>
and >>=
:
wordsCount = putStr "Write a line and press [enter]:\n" >> getLine >>= putStr . show . length . words >> putChar '\n'
Or making it easier to read:
wordsCount = putStr "Write a line and press [enter]:\n" >>
getLine >>=
putStr . show . length . words >>
putChar '\n'
A more straight-forward translation would be:
wordsCount = putStr "Write a line and press [enter]:\n" >>
getLine >>=
\s -> (putStr $ show $ length $ words s) >>
putChar '\n'
Basically the compiler converts such do
-notation blocks to its monadic equivalent (using only >>
and >>=
). do
is only syntactical sugar such that one does not have to write >>=
each time and/or mange variables.
Additional notes:
as @ChadGilbert said in his comment, the parenthesis should be wrapped around the function, excluding the \s ->
such that the s
can be used later on in the program, for example:
-- This is not an equivalent program
wordsCount = putStr "Write a line and press [enter]:\n" >>
getLine >>=
\s -> (putStr $ show $ length $ words s) >>
putChar '\n' >>
putStrLn s -- repeat s
Instead of using putStr
and putChar
, you can use putStrLn
. For example:
wordsCount = putStr "Write a line and press [enter]:\n" >>
getLine >>=
putStrLn . show . length . words