Haskell は遅延評価を行う純粋関数型言語です。値が実際必要になるまではプログラムは実行されませんから、実行する順序は保証されないのです。
入出力のときに実行する順序が保証されないとデータがバラバラになって困ります。ですから、実行する順序を保証する仕組みの IO モナドが提供されているのです。
実行する順序が保証ためですから、関数の奥深〜くで一旦 IOモナドを使えば、当然それを呼んでいる関数も実行する順序を保証しなければならないのです。
main :: IO ()
main = do cs <- readLine
putStrLn cs
readLine = do
cs <- getLine
return cs