Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: words count from a getLine without the "do" notation

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'
like image 752
John Doe Avatar asked Jun 08 '26 20:06

John Doe


1 Answers

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
    
like image 183
Willem Van Onsem Avatar answered Jun 11 '26 11:06

Willem Van Onsem