Saturday 28 May 2016

Haskell: withFile: Perform operation on file handle

Prelude System.IO> :t withFile
withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r

withFile function takes a file, OPMode and function (Handle -> IO r)  as an argument and produce some result IO r.The handle will be closed on exit from withFile.

FileUtil.hs
import System.IO

getLines :: Handle -> IO [String]
getLines h = hGetContents h >>= return . lines  

main = do
        putStrLn "Enter file name (Including full path) to read"
        fileName <- getLine

        information <- withFile fileName ReadMode $ \h -> getLines h >>= mapM_ putStrLn 
        putStrLn "Done processing"

$ cat today.txt 
The preparation for tomorrow is doing your best today.
$ 
$ ghc FileUtil.hs
Linking FileUtil ...
$ 
$ ./FileUtil
Enter file name (Including full path) to read
today.txt
The preparation for tomorrow is doing your best today.
Done processing

You can rewrite above program like below also.

FileUtil.hs
import System.IO

processData handle =
  do
   info <- hGetContents handle
   putStrLn info
   return "Processing Done"

main = do
        putStrLn "Enter file name (Including full path) to read"
        fileName <- getLine

        c <- withFile fileName ReadMode processData
        putStrLn c


Now update above program like below and re run, you will get error like file handle closed.

FileUtil.hs
import System.IO

main = do
        putStrLn "Enter file name (Including full path) to read"
        fileName <- getLine

        c <- withFile fileName ReadMode hGetContents
        putStrLn c


$ ghc FileUtil.hs
[1 of 1] Compiling Main             ( FileUtil.hs, FileUtil.o )
Linking FileUtil ...
$
$ ./FileUtil
Enter file name (Including full path) to read
today.txt
FileUtil: today.txt: hGetContents: illegal operation (delayed read on closed handle)


Any guess, why you got error, it is because hGetContents function is lazy, it won’t evaluate until required, and the handle will be closed on exit from withFile.

Following post explains it clearly
  
Previous                                                 Next                                                 Home

No comments:

Post a Comment