Haskell Language IO Reading words from an entire file


In Haskell, it often makes sense not to bother with file handles at all, but simply read or write an entire file straight from disk to memory, and do all the partitioning/processing of the text with the pure string data structure. This avoids mixing IO and program logic, which can greatly help avoiding bugs.

-- | The interesting part of the program, which actually processes data
--   but doesn't do any IO!
reverseWords :: String -> [String]
reverseWords = reverse . words

-- | A simple wrapper that only fetches the data from disk, lets
--   'reverseWords' do its job, and puts the result to stdout.
main :: IO ()
main = do
   content <- readFile "loremipsum.txt"
   mapM_ putStrLn $ reverseWords content

If loremipsum.txt contains

Lorem ipsum dolor sit amet,
consectetur adipiscing elit

then the program will output


Here, mapM_ went through the list of all words in the file, and printed each of them to a separate line with putStrLn.

If you think this is wasteful on memory, you have a point. Actually, Haskell's laziness can often avoid that the entire file needs to reside in memory simultaneously... but beware, this kind of lazy IO causes its own set of problems. For performance-critical applications, it often makes sense to enforce the entire file to be read at once, strictly; you can do this with the Data.Text version of readFile.