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'
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
 
    
    