Imperative Object Destruction
Hannah Schroeter
uk1o@rz.uni-karlsruhe.de
Mon, 13 Nov 2000 11:18:55 +0100
Hello!
On Mon, Nov 13, 2000 at 09:27:07AM -0000, Chris Angus wrote:
> why not create an abstract datatype
> OpenFile a which is a monad
> data OpenFile a = OpenFile (Maybe FileHandle -> IO a)
> and create you operations in terms of this
> openFile :: String -> OpenFile ()
> count :: OpenFile Int
> read :: Int -> OpenFile [Byte]
> then you could habe a run function
> runOF :: OpenFile a -> IO a
> which ran whatever you wanted for the file and ensured tahthe file was
> closed correctly afterwards.
> How we would do this with 2 files however I'm not so sure.
> [...]
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
or even, if you want both results without opening the file twice:
rewind :: Handle -> IO ()
(fileLength, fileContent) <- withOpenFile "filename" ReadMode $ \handle ->
do
len <- count handle
rewind handle
cont <- read handle
return (len, cont)
Two files:
result <- withOpenFile "file1" ReadMode $ \handle1 ->
withOpenFile "file2" ReadMode $ \handle2 ->
...
Kind regards,
Hannah.