
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 clarify: 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. Cheers Robert