That's the problem. And I think your solution is overly complicated.
Why not copy what Common Lisp does, just that Haskell can do it without macros:
withOpenFile :: FilePath -> IOMode -> (Handle -> IO a) -> IO a withOpenFile name mode action = do handle <- openFile name mode result <- (action handle) `finally` (hClose handle) return result
Usage:
count :: Handle -> IO Int read :: Handle -> IO [Byte]
fileLength <- withOpenFile "filename" ReadMode $ \handle -> count handle fileContent <- withOpenFile "filename" ReadMode $ \handle -> read handle
Doesn't fulfill condition 2:
2. no read or write operations are performed on file-handles that have not yet been opened, or that have already been closed.
...since you can do
stealHandle = withOpenFile "filename" ReadMode (\handle -> handle) stealHandle >>= read
If you want to enforce this kind of encapsulation using the type system, you could try using the runST trick, something like: withOpenFile :: FilePath -> IOMode -> (forall s . OpenFile s -> IO a) -> IO a of course, this needs the universal quantification extensions implemented in Hugs & GHC. Cheers, Simon
participants (1)
-
Simon Marlow