2

我想做这样的事情:

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"

当然,这不会按原样工作,因为我试图在尚未分配 cid 的代码块中使用 cid 。

这个想法是注册一个事件监听器,当它接收到一个事件时,它会注销自己并注册一个不同的事件监听器,它会来回做同样的事情。

4

1 回答 1

5

GHC 支持递归do

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

你也可以使用Control.Monad.Fix.

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

或者自己管理处理程序。

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

或者只是把所有东西都变成一个处理程序。

do ...
    ms <- newIORef False
    canvas `on` buttonPressEvent $ tryEvent do
        s <- readIORef ms
        if s
            then ...
            else ...
于 2011-02-24T21:57:03.947 回答