|
RE: Imperative Object Destruction: msg#00039lang.haskell.general
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. > -----Original Message----- > From: Ashley Yakeley [mailto:ashley@xxxxxxxxxxxx] > Sent: 13 November 2000 07:21 > To: Haskell List > Subject: Imperative Object Destruction > > > C++ provides a convenient mechanism for cleaning up stuff, the > destructor, which is guaranteed to get called when an object > passes out > of scope (or something). > > I'm wondering how to make a Haskell equivalent for imperative > code. For > instance, consider a simple file API, with these operations: > > open: given a string (the filename), open an existing file > with that > name, return a file-handle (or fail) > > count: given a file-handle, get the length of the file > > read: given a file-handle, offset into the file and a > number of bytes, > read the file returning a list of bytes (or fail) > > write: given a file-handle, offset into the file and a list > of bytes, > write the bytes to the file at the offset > > close: given a file-handle, close the handle > > In C++ I could simply create an OpenFile class, with the > close operation > in the destructor. The actual operations would be hidden from > OpenFile's > clients. > > I'd like to represent this API in Haskell so that the type-rules > guarantee that in any imperative action of type 'IO a', > > 1. every opened file gets closed exactly once > > 2. no read or write operations are performed on file-handles > that have > not yet been opened, or that have already been closed. > > My first guess was to create a function that encapsulated the entire > life-cycle of the file, passing in a function that would represent > whatever one wished to do on the file: > > count :: Handle -> IO Integer > read :: (Integer,Integer) -> Handle -> IO [Byte] > write :: (Integer,[Byte]) -> Handle -> IO () > withFile :: (Handle -> IO a) -> String -> IO a > > 'withFile operation name' would open the file called 'name', > perform the > operation 'operation', and then close the file. So for > instance, to get > the length of a file named "/home/ashley/foo": > > withFile count "/home/ashley/foo" > > Trouble is, one can easily pass a return function to withFile to get > ahold of the handle after it's been closed. > > My second guess was to use a special type to represent an imperative > operation that needed a handle: > > read :: (Integer,Integer) -> HandleOperation [Byte] > write :: (Integer,[Byte]) -> HandleOperation () > withFile :: HandleOperation a -> String -> IO a > > Of course, I'd then need to provide functions to compose/concatenate > HandleOperation values. But I can't help thinking this > problem is already > well-known and there's a straightforward solution... > > -- > Ashley Yakeley, Seattle WA > > > _______________________________________________ > Haskell mailing list > Haskell@xxxxxxxxxxx > http://www.haskell.org/mailman/listinfo/haskell > |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | RE: Imperative Object Destruction: 00039, Ashley Yakeley |
|---|---|
| Next by Date: | Re: Imperative Object Destruction: 00039, Hannah Schroeter |
| Previous by Thread: | RE: Imperative Object Destructioni: 00039, Ashley Yakeley |
| Next by Thread: | Re: Imperative Object Destruction: 00039, Hannah Schroeter |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |