Functional programming 在Elm 0.15中如何保持行为?
删除早期版本Elm中的功能时,Functional programming 在Elm 0.15中如何保持行为?,functional-programming,frp,elm,Functional Programming,Frp,Elm,删除早期版本Elm中的功能时,保持。我已经从0.14移植了一个Elm应用程序,但我一直在尝试让它的一部分工作,它使用keepWhen 所以基本上我在寻找一个函数,比如 keepWhen : Signal Bool -> a -> Signal a -> Signal a 我找到了 filter : (a -> Bool) -> a -> Signal a -> Signal a 但这不完全是一回事,我还没有弄明白如何让它工作。我在Elm 0.15中重
保持。我已经从0.14移植了一个Elm应用程序,但我一直在尝试让它的一部分工作,它使用keepWhen
所以基本上我在寻找一个函数,比如
keepWhen : Signal Bool -> a -> Signal a -> Signal a
我找到了
filter : (a -> Bool) -> a -> Signal a -> Signal a
但这不完全是一回事,我还没有弄明白如何让它工作。我在Elm 0.15中重新实现了keepWhen
中的信号过滤器。这取决于观察到的Signal.filter
使用信号值来决定是删除还是保留信号值,以及您可以组合两个信号以获得新信号(Signal.map2(,)
)
如果你将你所拥有的信号布尔
与你最终想要的信号a
结合起来,你将得到一个信号(a,布尔)
,你可以在信号中进行过滤
,只需提取布尔
值就可以决定是否保留该值
函数如下所示:
keepWhen : Signal Bool -> a -> Signal a -> Signal a
keepWhen cond def val =
let combined = Signal.map2 (,) val cond
filtered = Signal.filter snd (def, False) combined
final = Signal.map fst filtered
in final
它首先将“值”信号与Bool
信号配对,以获得信号(a,Bool)
。然后它根据信号中的Bool
对信号进行过滤,最后去掉Bool
,只保留“真实”值
您可以看到它在这里工作:。如果鼠标靠近(0,0)角,它将不会更新,但当鼠标移到右下角时,它将再次开始更新信号。回答:从实用程序包导入它
最简单的方法是从软件包中使用。
(完全披露:我是作者)
重要的实施细节
请注意,实现并不是完全微不足道的。这是包中的实现(导入的信号模块不合格):
与中版本的重要区别在于sampleOn
,它可以防止的输出在布尔输入更改时更新。这两个过滤器之间的区别在于keepWhen
from 0.14实际上只过滤a
输入中的更新事件,并且在布尔输入变为True
时不对其进行采样
另一个实现也是名为signalextra的
图表
如果你对大理石图略知一二,也许会有所帮助。我将在下面发布相关内容的截图
您阅读这些图表的方式:
时间从左向右流动
线路是一种信号
块是一个函数,它接收上面的两个信号并生成下面的信号
每行左侧的形状是初始值
填充形状是信号上的事件
轮廓形状适用于信号不变的情况
我用形状来表示类型
我用颜色来代表不同的价值观李>
请注意,标记为旧行为的第二个图表与kqr答案中代码的行为相匹配 非常优雅!我听说0.12版本之前的keepWhen和“现代”版本之间存在差异,但直到你现在非常清楚地解释了这一差异,我才理解这一差异。非常感谢!
keepWhen : Signal Bool -> a -> Signal a -> Signal a
keepWhen boolSig a aSig =
zip boolSig aSig
|> sampleOn aSig
|> keepIf fst (True, a)
|> map snd