[Xmonad] darcs patch: fix bug leading to early exit in XPrompt.
David Roundy
daveroundy at gmail.com
Tue Aug 28 14:14:15 EDT 2007
On Tue, Aug 28, 2007 at 07:51:48PM +0200, Andrea Rossato wrote:
> On Tue, Aug 28, 2007 at 10:08:58AM -0400, David Roundy wrote:
> > You're welcome! Basically, I just used the printf approach, combined with
> > code review, in which I just searched for cases where eventLoop might have
> > exited early. There's got to be a better idiom for writing an event loop.
> > (so that exiting the loop is done explicitly, rather than
> > implicitly... which would make it harder to exit the loop accidentally.)
>
> yes, indeed. Since I suspect you already have an idea on how the idiom
> should look like, may I ask you:
> - what would you suggest? -
> ;-)
I'm not sure. My only idea would be to use exceptions to exit the loop.
Then you could have something like (I'll write my example in IO, but you
can extrapolate)
eventLoop :: (EventType -> IO ()) -> IO ()
eventLoop job = forever (getNextEvent >>= job) `catchJust` breakException
(\_ -> cleanup)
forever a = a >> forever a
exitLoop :: IO ()
where breakException should be a function that probably uses dynException
to filter out only exceptions thrown by exitLoop.
Another option would be to avoid exceptions and instead make the job return
explicitly whether or not to continue
eventLoop :: (EventType -> IO ContinueOrNot) -> IO ()
eventLoop job = do done <- getNextEvent >>= job
case done of
ExitNow -> cleanup
KeepGoing -> eventLoop job
data ContinueOrNot = ExitNow | KeepGoing
This makes the code a bit cleaner, and also has the advantage of working in
monads that don't support exceptions. It means that every branch of the
job has to explicitly decide whether or not to keep going, but at least the
compiler will enforce that you need to have a clear decision on each
branch.
But I'm not sure either of these is optimal. Exceptions are ugly. You
could also (given you're in a state monad) throw a "stop now" flag into
that state, which is perhaps better than either of these. Then you'd only
need to specify exitLoop (or whatever you choose to call it)...
--
David Roundy
http://www.darcs.net
More information about the Xmonad
mailing list