14

我目前正在尝试通过 Heinrich Apfelmus 的reactive-banana来了解 FRP ,与我看过的其他库相比,它似乎是一个文档齐全且简单的库。

但是,我无法理解 AddHandler类型。假设我想使用GLFW来获得鼠标按钮点击,这样我就有了类似eMouseButton :: Event (). 查看示例,似乎我不得不以某种方式使用fromAddHandler,但我不知道如何组合该AddHandler论点。我想我必须以newAddHandler某种方式使用,但是如何?

我想一个如何连接reactive-banana到其他东西的例子wx会很有帮助。

4

1 回答 1

14

newAddHandler像这样使用:

do (addHandler, fire) <- newAddHandler
   ...

addHandler是要传递给的 AddHandler reactive-banana,并且fire是触发事件的类型函数a -> IO ()(其中a是您的事件类型)。

例如,您可能会安装fire为 GLFW 鼠标按钮事件的回调,如下所示:

registerMouseButton :: IO (Event MouseButton)
registerMouseButton = do
  (addHandler, fire) <- newAddHandler
  setMouseButtonCallback $ \button _ -> fire button
  fromAddHandler addHandler

(我没有使用 GLFW 的经验,所以我不确定setMouseButtonCallback's 回调的第二个参数是什么——如果它很重要,你需要适当地修改这个实现。)

AnAddHandler只是一个接受回调的函数a -> IO ()——并为相关事件注册它;然后它(从内部)返回一个用于取消注册此处理程序的操作,使 read 的完整定义如下:IOIO ()AddHandler

type AddHandler a = (a -> IO ()) -> IO (IO ())

那么从哪里newAddHandler进来呢?简单:newAddHandler维护一个事件的处理程序列表,并在fire x执行时激活它们。

newAddHandler如果像 GTK+ 和许多其他常用工具包一样,您的工具包已经具有注册和注销多个事件处理程序的功能,则您不需要;如果是这样,您应该编写自己的AddHandler. 但是如果它只支持一个回调,你应该使用newAddHandler.

请注意,您永远不需要将AddHandlers 暴露给使用 FRP 的代码本身;它们只是用于Event从外部输入创建 s 的内部粘合剂。

于 2011-12-25T22:14:29.297 回答