2

I would like to do something like this:

handlerOn = do
  cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOff
  putStrLn "handlerOn"

handlerOff = do
  cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOn
  putStrLn "handlerOff"

This won't work as it is, of course, because I'm trying to use cid inside a code block where cid is not assigned yet.

The idea is to register an event listener that when it receives an event, it will deregister itself and register a different event listener which will do the same, back and forth.

mentics
  • 6,852
  • 5
  • 39
  • 93

1 Answers1

5

GHC supports recursive do.

handlerOn = do
  rec cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOff
  putStrLn "handlerOn"

You could also use Control.Monad.Fix.

handlerOff = do
  mfix $ \cid -> canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOn
  putStrLn "handlerOff"

Or manage the handler yourself.

do ...
    h <- newIORef undefined
    let handlerOn = do
            ...
            writeIORef h handlerOff
        handlerOff = do
            ...
            writeIORef h handlerOn
    writeIORef h handlerOn
    canvas `on` buttonPressEvent $ tryEvent =<< readIORef h

Or just make everything into a single handler.

do ...
    ms <- newIORef False
    canvas `on` buttonPressEvent $ tryEvent do
        s <- readIORef ms
        if s
            then ...
            else ...
ephemient
  • 198,619
  • 38
  • 280
  • 391
  • 2
    Thanks! I'm using the first option and at least for me, I had to add braces as in: rec { cid ... handlerOff } for it to work. – mentics Feb 25 '11 at 05:48