4
我正在阅读Conal Elliot的论文"Declarative Event-Oriented Programming",其中的例子是使用现在已经过时的Fran库编写的。ifB在反应香蕉中的实现
当我学习FRP时,我试着用反应式香蕉来实现这些例子。我似乎没有这个问题(但必须认为很多 :))。唯一我不明白的是如何正确翻译Fran的ifB
。
它似乎有这种类型的签名:
ifB :: Behavior Bool -> Behavior a -> Behavior a -> Behavior a
但反应香蕉只有switchB
对于这样的事情。
目前我设法通过添加将用于切换的行为,这样的一个额外的“触发”事件来做到这一点:
ifB :: MonadMoment m => Event b -> BoolB -> Behavior a -> Behavior a -> m (Behavior a)
ifB trigger condB b1 b2 = switchB b2 (switcherB <@ trigger)
where switcherB = (\x -> if x then b1 else b2) <$> condB
我不知道这是否是一个正确和良好的解决方案。它是高性能的吗? 下面是从使用ifB
论文片段:
editCPoint :: User -> S.Point2 -> CPoint
editCPoint u p0 = (pos, closeEnough)
where
pos, lastRelease :: Point2B
-- vvv this is the ifB in question!
pos = ifB grabbing (mouse u) lastRelease
lastRelease = stepper p0 (release ‘snapshot_‘ pos)
closeEnough, grabbing :: BoolB
closeEnough = distance2 pos (mouse u) <* grabDistance
grabbing = stepper False (grab -=> True .|. release -=> False)
grab, release :: Event()
grab = lbp u ‘whenE‘ closeEnough
release = lbr u ‘whenE‘ grabbing
grabDistance :: RealB
grabDistance = 2 * pointSize
我设法得到这个片段与无功香蕉的工作,通过使用我的实施ifB
,所以它得到定期更新喂养它一个cursor move
事件。我试图喂它只有鼠标按下/释放事件作为触发器切换,它不能正常工作...
我做错了吗?有关如何做得更好的建议?
非常感谢你,它再次尚未那一刻当我想到“为什么我没有看到这个?”在学习Haskell时经常会碰到我。我喜欢这个 :) – dimsuz