reactive-banana:如何创建AddHandler?

时间:2011-12-25 22:06:58

标签: haskell reactive-programming reactive-banana

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

但是,我无法绕过AddHandler类型。假设我想使用GLFW来获取鼠标按钮,这样我就可以使用eMouseButton :: Event ()。看一下这些例子,似乎我不得不使用fromAddHandler,但我不知道如何组装AddHandler参数。我想我不得不以某种方式使用newAddHandler,但是如何?

我想如何将reactive-banana连接到除wx以外的其他内容的示例会有很大帮助。

1 个答案:

答案 0 :(得分:14)

newAddHandler的使用方式如下:

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

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

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

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

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

AddHandler只是一个接受回调的函数 - a -> IO () - 并为相关事件注册它;然后返回(来自IO内)用于取消注册此处理程序的IO ()操作,使complete definition of AddHandler读取如下:

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

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

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

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