[Haskell-cafe] letting go of file handles and Data.Binary

Daniel Fischer daniel.is.fischer at web.de
Sun Apr 20 20:34:32 EDT 2008


Am Montag, 21. April 2008 01:35 schrieb Ben:
> FWIW, installed bytestring-0.9.1.0, ran ghc-pkg hide
> bytestring-0.9.0.1, recompiled and reinstalled binary-0.4.1.  then i
> played around with all that you suggested, and came to the conclusion
> that i don't understand seq!
>
> import Control.Exception (bracket)
> import System.Directory
> import System.IO
> import Data.Binary
> import Data.ByteString.Lazy as B
>
> strictDecodeFile :: Binary a => FilePath -> (a -> b) -> IO ()
> strictDecodeFile path force =
>     bracket (openFile path ReadMode) hClose $ \h -> do
>       c <- B.hGetContents h
>       force (decode c) `seq` return ()

This means that force (decode c) is reduced to head normal form, not fully 
evaluated. So if the result type of force were e.g. Either String Int, it 
would be evaluated just far enough to determine if force (decode c) is
bottom,
Left something or
Right somethingelse;
Left undefined and Right undefined won't cause an exception.
In the case below, force (decode c) is an IO action, it will be evaluated as 
far as necessary to see it's (IO whatever) and not bottom, for that it need 
not be run, therefore you don't see "strict 1" printed out.

>
> strictDecodeFile' :: Binary a => FilePath -> (a -> IO b) -> IO ()
> strictDecodeFile' path force =
>     bracket (openFile path ReadMode) hClose $ \h -> do
>       c <- B.hGetContents h
>       force (decode c)
>       return ()

Here you say you want the IO action force (decode c) to be run, so it is run 
and "strict 2" is printed out.

Hope that helps.


More information about the Haskell-Cafe mailing list