我正在学习反应香蕉。为了理解该库,我决定实现一个虚拟应用程序,该虚拟应用程序将在有人按下按钮时增加计数器。
我正在使用的UI库是Gtk,但这与说明无关。
这是我想出的非常简单的实现:
import Graphics.UI.Gtk
import Reactive.Banana
import Reactive.Banana.Frameworks
makeNetworkDescription addEvent = do
eClick <- fromAddHandler addEvent
reactimate $ (putStrLn . show) <$> (accumE 0 ((+1) <$ eClick))
main :: IO ()
main = do
(addHandler, fireEvent) <- newAddHandler
initGUI
network <- compile $ makeNetworkDescription addHandler
actuate network
window <- windowNew
button <- buttonNew
set window [ containerBorderWidth := 10, containerChild := button ]
set button [ buttonLabel := "Add One" ]
onClicked button $ fireEvent ()
onDestroy window mainQuit
widgetShowAll window
mainGUI
这只是将结果转储到shell中。我阅读了Heinrich Apfelmus的文章,提出了这个解决方案。请注意,在我的示例中,我没有使用过一个Behavior
。
本文中有一个网络示例:
makeNetworkDescription addKeyEvent = do
eKey <- fromAddHandler addKeyEvent
let
eOctaveChange = filterMapJust getOctaveChange eKey
bOctave = accumB 3 (changeOctave <$> eOctaveChange)
ePitch = filterMapJust (`lookup` charPitches) eKey
bPitch = stepper PC ePitch
bNote = Note <$> bOctave <*> bPitch
eNoteChanged <- changes bNote
reactimate' $ fmap (\n -> putStrLn ("Now playing " ++ show n))
<$> eNoteChanged
该示例显示了stepper
将a转换Event
为aBehavior
并带回Event
using的changes
。在上面的示例中,我们只能使用Event
,我想这不会有任何区别(除非我不了解某些内容)。
因此,有人可以阐明何时使用Behavior
以及为什么使用吗?我们应该Event
尽快转换所有s吗?
在我的小实验中,我看不到Behavior
可以使用的地方。
谢谢
每当FRP网络在“反应性香蕉”中“做某事”时,都是因为它对某些输入事件做出了反应。而且,它只能在外部系统上进行连接以对其生成的事件做出反应(使用reactimate
),从而在系统外部执行任何可观察的操作。
因此,如果您要做的只是立即通过产生输出事件来对输入事件做出反应,那么不会,您不会发现有太多使用的理由Behaviour
。
Behaviour
对于产生依赖于多个事件流的程序行为非常有用,您必须记住事件在不同的时间发生。
一个Event
有出现; 具有价值的特定时间点。ABehaviour
在所有时间点都具有一个值,没有特殊的时间瞬间(除外changes
,这很方便,但有点违反模型)。
许多GUI都熟悉的一个简单示例是,如果我想对鼠标单击做出反应,并在不按住Shift键的情况下让Shift-Click进行与单击不同的操作。随着Behaviour
保持表示Shift键是被按住的值,这是微不足道的。如果我只有Event
Shift键的按下/释放和鼠标的单击,则要困难得多。
除了更难,它的水平要低得多。为什么仅为了实现像shift-click这样的简单概念就必须进行复杂的摆弄?在选择之间Behaviour
,并Event
可以以更接近映射到你想想他们的编程世界之外的方式实施方面你的程序的概念,一个有用的抽象。
这里的一个示例是游戏世界中的可移动对象。我可以随时随地Event Position
代表自己。或者,我可以随时Behaviour Position
代表自己的位置。通常我会成为对象的思想具有在任何时候的位置,所以Behaviour
是一个更好的概念契合。
另一个Behaviour
有用的地方是表示程序可以进行的外部观察,在这里只能检查“当前”值(因为发生更改时外部系统不会通知您)。
例如,假设您的程序必须在温度传感器上保持标签,并避免在温度过高时开始工作。有了Event Temperature
I,我将预先决定轮询温度传感器的频率(或响应什么)。然后遇到与其他示例相同的问题,即必须手动执行某些操作才能使事件的最后温度读数可用,从而决定是否开始工作。或者我可以fromPoll
用来做一个Behaviour Temperature
。现在,我有一个代表温度随时间变化的值,并且完全摆脱了对传感器的轮询。活性香蕉本身会尽可能地轮询传感器,而我根本不需要为此付出任何逻辑!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句