In haskell there are two ways to read the stdin stream. Which one to use depends on what you’re trying to accomplish I guess.

Either you can read each line in a loop.

import System.IO

main = myLoop

myLoop = do done <- isEOF
            if done
              then putStrLn ""
              else do inp <- getLine
                      putStrLn inp
                      myLoop

We call the myLoop function recursively until getLine returns EOF. Every time we get a string back, we print it to stdout and call ourselves again.

The other method involves reading the entire stream with getContents and then lazily read each line.

import Data.Char

main :: IO ()
main = do
   inp <- getContents
   let ls = lines inp
   mapM_ putStrLn ls

Here we get the stream into inp, split that into an array of lines, and map that array to the putStrLn function, which prints to stdout.