Haskell: Reading files

In writing the clustering algorithm which I’ve mentioned way too many times already I needed to process a text file which contained all the points and my initial approach looked like this:

import System.IO
main = do    
    withFile "clustering2.txt" ReadMode (\handle -> do  
        contents <- hGetContents handle   
        putStrLn contents)

It felt a bit clunky but I didn’t realise there was an easier way until I came across this thread. We can simplify reading a file to the following by using the readFile function:

main = do    
    contents <- readFile "clustering2.txt" 
    putStrLn contents

We need to read the file in the IO monad which explains why we have the ‘do’ notation on the first line.

Another thing I didn’t realise until recently was that you don’t actually need to worry about the ‘do’ notation if you try to read from the IO monad inside GHCI.

In this context we’re reading from the IO monad when we bind ‘readFile’ to the variable ‘contents’ since ‘readFile’ returns type ‘IO String':

> :t readFile
readFile :: FilePath -> IO String

We can therefore play around with the code pretty easily:

> contents <- readFile "clustering2.txt"
> let (bits, nodes) = process contents 
> bits
> length nodes
> take 10 nodes

I think we’re able to do this because by being in GHCI we’re already in the context of the IO monad but I’m happy to be corrected if I haven’t explained that correctly.

Be Sociable, Share!