"callbacks" in Haskell

Robert Vollmert rvollmert@gmx.net
Thu, 26 Jun 2003 12:33:22 +0200

Tom Pledger wrote:
> Robert Vollmert writes:
>  | I've been having a little trouble writing a module that waits for and
>  | handles IO events, e.g. by reading from a pipe. It seemed natural to
>  | use some form of callbacks here, though that may very well be the
>  | wrong approach. I'd be happy to hear of alternatives.

> Can the event and handler inhabit the same monad, say IO?  If so, is
> the following the sort of thing you had in mind?
>     waitAndHandleOneEvent      :: IO e -> (e -> IO ()) -> IO ()
>     waitAndHandleOneEvent ioe h = forkIO (do e <- ioe
>                                              h e)

Thanks for your reply. I was really hoping to do this without
concurrency, though. Also, since I'd like to keep some extra state in
the event loop, I'd like to be able to extend the monad. I'll try to

I'd like to yield control to an IO action, which would run the
callback on receiving an event. Like:

handleEvents :: (Event -> IO ()) -> IO ()
handleEvents callback = do e <- getEvent
                           callback e
                           handleEvents callback

However, I'd like to
* not require IO, but any MonadIO (this shouldn't be a problem, I think)
* extend the base monad in my event loop (no problem either) and
* allow the callback to access this (which is where it gets difficult)

In the case of reading events from a pipe, the extension in b) might
consist of storing a handle to the pipe. Then, maybe I'd want to
provide (in the extended monad) an action closePipe, which I'd like
the callback to be able to call.