对Yampa交换机的图表感到困惑

时间:2014-08-19 05:20:15

标签: haskell functional-programming reactive-programming frp yampa

Yampa开关有一些图表:

http://www.haskell.org/haskellwiki/Yampa/switch

http://www.haskell.org/haskellwiki/Yampa/rSwitch

http://www.haskell.org/haskellwiki/Yampa/kSwitch

(依此类推)。

我发现switch是唯一一个有描述的图表,是最容易理解的图表。其他人似乎很难按照类似的符号来阅读图表。例如,尝试使用rSwitch中使用的符号阅读switch可能是:

  

是一个递归SF,总是输入'in'和'的类型信号   返回“out”类型的信号。从相同的初始SF开始   类型,但切换功能以外的人(?[cond])square)可能   还通过事件传递新的SF(类型Event (SF in out)在   条件满足时(对于'?')   [cond] square)。如果是事件,Yampa将使用新的SF   而不是现有的。这个过程是递归的,因为'?' (不能   从图中得到它,除了rSwitch的签名似乎   递归)。

在我查看rSwitch的源代码之后,看起来它使用switcht被触发时递归切换到相同的init SF(根据该图,虽然我没有看到在源代码中会触发特殊的t。)

在Yampa Arcade中,它用代码和示例解释了dpSwitch。关于游戏'Frag'的论文也使用了dpSwitch。但是,这些教程中似乎没有rSwitch。所以我真的不知道如何使用r-k-串行开关,以及在什么情况下我们需要它们。

1 个答案:

答案 0 :(得分:4)

所有switch函数都是将信号函数更改为另一种信号函数的方法。我个人觉得Yampa图表有点难以解析,但各种开关的类型签名给出了如何理解它们的良好指示。一旦理解了类型签名,图表就会变得更加清晰。 switch本身是最基本的:

switch :: SF a (b, Event c) -> (c -> SF a b) -> SF a b

如果我们查看类型,它会准确地告诉我们它的作用:它需要一个SF sf和一个SF生成器sfgsf生成类型(b, Event c)的值,信号函数生成器的输入也恰好是c类型。因此,每当发生sf事件时,SF将切换到SF生成器的结果。在事件发生之前,生成的SF将返回原始SF的值。

这个想法也用于rswitchkswitch变体,但有点不同。


rswitch:这被称为“外部开关”,意味着SF将在不对其输入或输出进行任何分析的情况下进行切换。我们来看一下类型签名:

rswitch :: SF a b -> SF (a, Event (SF a b)) b

它采用单个SF作为类型a的输入值,并输出类型b的值。 rswitch创建一个新的SF,它也会生成输出b,但需要另外输入Event (SF a b)类型的输入。请注意,Event值的类型与输入类型匹配。这意味着每当事件发生时,此SF将切换到该事件值。但是,SF的类型仍为SF (a, Event (SF a b)) b。这意味着SF可以自由地接收具有新SF的附加事件,这将影响整个SF的行为。一个用途可能是游戏中的AI行为:

moveFollowTarget :: SF TargetPosition Velocity
moveShootTarget :: SF TargetPosition Velocity
moveIdle :: SF TargetPosition Velocity

aiMovement :: SF (TargetPosition, Event (SF TargetPosition Velocity)) Velocity
aiMovement = rswitch moveIdle  -- Initially idle...

aiMovementManager :: SF a (Event (SF TargetPosition Velocity))
aiMovementManager = ... whatever ...

这里,只要AI的移动行为需要改变,aiMovementManager就会触发事件,事件的值将是移动应该改变的SF。


kswitch:这被称为intrinsic switch,因为分析了SF的内容以确定正确的开关应该是什么。让我们回顾一下类型签名

kswitch :: SF a b -> SF (a, b) (Event c) -> (SF a b -> c -> SF a b) -> SF a b

此处,kswitch有三个参数:sfanalyzermappingsf只是标准SF,输入类型为a,输出类型为bsf是信号最初的表现方式。 analyzer是一个SF,它接受sf的输入和输出,可能会或可能不会触发某些值为c的事件。如果它没有触发事件,则没有任何反应,SF继续表现为sf。如果它触发事件,则sf和事件值都将传递给mapping,这将确定要切换到的新SF。在根据输出更改系统行为的方式时,kswitch非常有用。

有用的一个例子是TCP Congestion Avoidance的算法。在这里,我们看看我们是否丢失网络数据包,并提高或降低我们请求数据的速度。