为什么要在FRP中使用行为

Mathk

我正在学习反应香蕉。为了理解该库,我决定实现一个虚拟应用程序,该虚拟应用程序将在有人按下按钮时增加计数器。

我正在使用的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

该示例显示了steppera转换Event为aBehavior并带回Eventusing的changes在上面的示例中,我们只能使用Event,我想这不会有任何区别(除非我不了解某些内容)。

因此,有人可以阐明何时使用Behavior以及为什么使用吗?我们应该Event尽快转换所有s吗?

在我的小实验中,我看不到Behavior可以使用的地方。

谢谢

Ben

每当FRP网络在“反应性香蕉”中“做某事”时,都是因为它对某些输入事件做出了反应。而且,它只能在外部系统上进行连接以对其生成的事件做出反应(使用reactimate,从而在系统外部执行任何可观察的操作

因此,如果您要做的只是立即通过产生输出事件来对输入事件做出反应,那么不会,您不会发现有太多使用的理由Behaviour

Behaviour对于产生依赖于多个事件流的程序行为非常有用,您必须记住事件在不同的时间发生

一个Event有出现; 具有价值的特定时间点。ABehaviour在所有时间点都具有一个值,没有特殊的时间瞬间(除外changes,这很方便,但有点违反模型)。

许多GUI都熟悉的一个简单示例是,如果我想对鼠标单击做出反应,并在不按住Shift键的情况下让Shift-Click进行与单击不同的操作。随着Behaviour保持表示Shift键是被按住的值,这是微不足道的。如果我只有EventShift键的按下/释放和鼠标的单击,则要困难得多。

除了更难,它的水平要低得多。为什么仅为了实现像shift-click这样的简单概念就必须进行复杂的摆弄?选择之间Behaviour,并Event可以以更接近映射到你想想他们的编程世界之外的方式实施方面你的程序的概念,一个有用的抽象。

这里的一个示例是游戏世界中的可移动对象。可以随时随地Event Position代表自己。或者,我可以随时Behaviour Position代表自己的位置。通常我会成为对象的思想具有在任何时候的位置,所以Behaviour是一个更好的概念契合。

另一个Behaviour有用的地方是表示程序可以进行的外部观察,在这里只能检查“当前”值(因为发生更改时外部系统不会通知您)。

例如,假设您的程序必须在温度传感器上保持标签,并避免在温度过高时开始工作。有了Event TemperatureI,我将预先决定轮询温度传感器的频率(或响应什么)。然后遇到与其他示例相同的问题,即必须手动执行某些操作才能使事件的最后温度读数可用,从而决定是否开始工作。或者我可以fromPoll用来做一个Behaviour Temperature现在,我有一个代表温度随时间变化的值,并且完全摆脱了对传感器的轮询。活性香蕉本身会尽可能地轮询传感器,而我根本不需要为此付出任何逻辑!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么要在AngularJS中使用$ onInit?

来自分类Dev

为什么要在golang中使用组合?

来自分类Dev

为什么要在 Angular 中使用 ValueAccessor?

来自分类Java

为什么要在Android中使用RequestQueue?

来自分类Dev

为什么要在Dialogflow中使用动作

来自分类Dev

为什么要在结构中使用malloc?

来自分类Dev

为什么要在延迟中使用setTimeout

来自分类Dev

为什么要在laravel中使用npm?

来自分类Dev

为什么要在Flux中使用“动作”?

来自分类Dev

为什么要在Flink中使用kafka

来自分类Dev

为什么要在Typescript中使用接口

来自分类Dev

为什么要在ListView中使用DataTemplate?

来自分类Dev

什么是背景?为什么要在odoo中使用?

来自分类Javascript

为什么要在JavaScript变量的名称中使用$(美元符号)?

来自分类Dev

为什么要在该程序中使用fflush(stdin)?

来自分类Dev

为什么要在Git中使用core.autocrlf = true?

来自分类Dev

为什么要在Java卡程序中使用“ setSeed()”?

来自分类Java

为什么要在main方法中使用SwingUtilities.invokeLater?

来自分类Dev

为什么要在“ if”语句中使用语句?

来自分类Java

为什么要在Java中使用`transient`关键字?

来自分类Dev

蜂巢:为什么要在选择中使用分区?

来自分类Dev

为什么要在Dropwizard指标中使用CachedGauage?

来自分类Dev

为什么要在执行脚本中使用bash?

来自分类Dev

为什么要在DI中使用`deps`属性

来自分类Dev

为什么要在python中使用`iter`函数

来自分类Linux

为什么我要在Dockerfile中使用VOLUME?

来自分类Dev

为什么要在Python中使用导入BaseHTTPServer?

来自分类Dev

为什么要在实时处理中使用Apache Kafka

来自分类Java

为什么要在Spring中使用self类?

Related 相关文章

热门标签

归档