
The following code runs out of file handles, so I am seeking enlightenment as to why.
-- | add data from a file to the histogram addFile :: FiniteMap String Int -> String -> IO (FiniteMap String Int) addFile fm name = do x <- readFile name return (addHist fm x)
-- | add data from all files in a directory to the histogram addDir :: FiniteMap String Int -> String -> IO (FiniteMap String Int) addDir fm dir = do dc <- getDirectoryContents dir fs <- filterM doesFileExist (map ((dir++"/")++) dc) foldM addFile fm fs
Running addDir on a directory with few hundred files trigs it. Shouldn't all of each file's contents be consumed by each addFile, and thus the handle be released?
It's not possible to tell from this code whether the readFiles will be fully evaluated or not: it depends on how much evaluation addHist does, and to what extend the result FiniteMap is demanded, amongst other things. These things are always tricky to understand, which is why I recommend not using lazy I/O. File reading is not a pure operation: running out of file descriptors is a good counter-example. Cheers, Simon