[Haskell-cafe] IO and lazyness.

Matthew Brecknell haskell at brecknell.org
Tue Mar 6 17:10:48 EST 2007

Daniel McAllansmith:
> The problem is that hGetContents only reads the contents of the file on
> demand 
> and, without the 'return $!' you don't demand the value until somewhere 
> outside of rechf.  By this point the hClose has happened and hGetContents
> has 
> no access to the file => no lines => no result.
> Using 'return $!' is demanding the value of rech r $ lines f immediately
> so 
> hGetContents accesses the file before the hClose.
> hGetContents is implemented using unsafePerformIO so, unless you're very 
> careful, you could get other weird behaviours.

For example, if the value for the key being searched is very long (>8k
on my system), it is likely to be truncated. This is because "return $!"
only reduces its argument to WHNF. In other words, it only demands
enough to work out whether the key is present, which means that
hGetContents only gets a chance to return the first block of data
retrieved after the key is found, before the file is closed.

So, instead of "return $! rech r $ lines f", you really need something

case (rech r $ lines f) of
  Just s -> return $! Just $! foldr seq s s
  Nothing -> return Nothing

More information about the Haskell-Cafe mailing list