[Haskell-beginners] lazy IO in readFile
Stephen Blackheath [to Haskell-Beginners]
mutilating.cauliflowers.stephen at blacksapphire.com
Sun May 16 07:03:03 EDT 2010
Andrew,
On 15/05/10 11:57, Andrew Sackville-West wrote:
> I'm having trouble determining how to put this into the existing
> context of a string of filter's and maps where the contents of the
> file are used in a predicate to a filter. (if you really want you can
> look at my ridiculous code at
> http://git.swclan.homelinux.org/rss2email.git)
I took a look. You've got a list of items and you want to check each
one against your 'seen it' file. I'm not sure what your requirements
are but currently the whole file gets read into memory. So, sticking
with that, here's _a_ way to do it (with a Set, which gives a faster
lookup):
import Control.Exception
import Data.Set (Set)
import qualified Data.Set as S
import System.IO.Error
import Prelude hiding (catch)
-- | Return "seen it" predicate
readHistory :: FilePath -> IO (String -> Bool)
readHistory fn = do
hist <- withFile fn ReadMode $ \h -> fetchLines h S.empty
return (`S.member` hist)
where
fetchLines h hist = do
l <- hGetLine h
fetchLines h $! S.insert l hist
`catch` \exc ->
if isEOFError exc
then return hist
else throwIO exc
This is completely strict. The $! is there to make sure we're keeping a
set in memory, not a chain of inserts (though the inserts wouldn't
actually take up any more memory than the set does). I haven't tried
compiling this.
Steve
More information about the Beginners
mailing list