我试图了解这种函数式反应式编程是如何工作的,但我遇到了一个问题。我正在尝试创建一个boid 模拟,但我开始的速度很慢,我现在已经将一个 boid 定义为一个函数,它采用一个起始位置并创建一个从一个位置到一个位置的信号函数,其中输入是点它正在移动,输出是当前位置:
type Position2 = Vector2 Float
boid :: Position2 -> SF Position2 Position2
boid s = loop (arr (uncurry seek) >>> integral >>> arr (^+^ s) >>> arr dup)
seek 函数需要两个输入(因为循环)。当前位置和目标位置。然后它只是创建一个从当前位置指向目标位置的向量,其大小为 50,即速度。然后对速度进行积分并添加起始位置。最后,信号被一分为二,一个可以成为输出,另一个可以循环回搜索功能。
现在我可以像这样定义 boids:
aBoid = constant (vector2 500 500) >>> (boid (vector2 600 60))
bBoid = aBoid >>> (boid (vector2 3 4))
这里 aBoid 向点 (500, 500) 寻找,而 bBoid 向 aBoid 寻找。
我的问题是,当我希望这两个 boids 互相寻找时。当我这样做时:
aBoid = bBoid >>> (boid (vector2 600 60))
bBoid = aBoid >>> (boid (vector2 3 4))
该程序只是打印:ProgramName: <<loop>>
我认为这意味着它进入了一个无限循环。
我也尝试过使用这样的par
功能:
sim :: SF a [Position2]
sim = loop (arr snd >>> par route [boid (vector2 10 10), boid (vector2 100 100)] >>> arr dup)
这里route
函数只是将每个 boid 的输出映射到另一个 boid 的输入(如zip
,但偏移量为 1)
这也给出了<<loop>>
信息。
我认为在处理反应式系统时,让对象依赖于彼此的状态应该是一个很常见的问题,所以我希望有一些优雅的解决方案。
我应该补充一点,我发现这个 FRP 东西非常困难并且经常令人困惑,所以我不确定我是否有道理;)