Elm 用另一个信号的值过滤一个信号

Elm 用另一个信号的值过滤一个信号,elm,Elm,我想为鼠标位置创建一个过滤信号。当鼠标按钮按下,或者鼠标从“不向下”切换到“向下”时,它应该更新 我提出了这个函数。它可以工作,但使用三个匿名函数似乎不正确。有没有一种惯用的方法可以做到这一点 mouseDownPosition: Signal (Int, Int) mouseDownPosition = Signal.map2 (\(x, y) isDown -> (x, y, isDown)) Mouse.position Mouse.isDown |> Signal.

我想为鼠标位置创建一个过滤信号。当鼠标按钮按下,或者鼠标从“不向下”切换到“向下”时,它应该更新

我提出了这个函数。它可以工作,但使用三个匿名函数似乎不正确。有没有一种惯用的方法可以做到这一点

mouseDownPosition: Signal (Int, Int)
mouseDownPosition = 
  Signal.map2 (\(x, y) isDown -> (x, y, isDown)) Mouse.position Mouse.isDown
  |> Signal.filter (\(x, y, isDown) -> isDown) (0, 0, False)
  |> Signal.map (\(x, y, isDown) -> (x, y))

在发布问题时,我想出了如何避免匿名函数。不过,我觉得有一个更优雅的解决方案

mouseDownPosition: Signal (Int, Int)
mouseDownPosition = 
  Signal.map2 (,) Mouse.position Mouse.isDown
  |> Signal.filter snd ((0, 0), False)
  |> Signal.map fst

在发布问题时,我想出了如何避免匿名函数。不过,我觉得有一个更优雅的解决方案

mouseDownPosition: Signal (Int, Int)
mouseDownPosition = 
  Signal.map2 (,) Mouse.position Mouse.isDown
  |> Signal.filter snd ((0, 0), False)
  |> Signal.map fst

我更喜欢@joews解决方案,但为了另一种选择,这里有另一个版本:

mouseDownPosition: Signal (Int, Int)
mouseDownPosition = 
  Signal.map2 (\p d -> if d then Just p else Nothing) Mouse.position Mouse.isDown
  |> Signal.filterMap identity (0,0)

我更喜欢@joews解决方案,但为了另一种选择,这里有另一个版本:

mouseDownPosition: Signal (Int, Int)
mouseDownPosition = 
  Signal.map2 (\p d -> if d then Just p else Nothing) Mouse.position Mouse.isDown
  |> Signal.filterMap identity (0,0)
图书馆职能 有一个名为“完全公开”的信号实用程序库:我是该库的作者,该库有一个函数用于以下内容::Signal Bool->a->Signal a->Signal a

[…]过滤器,只要信号布尔值为真,它就会保留来自信号a的事件

实施 如果你想知道的话,它的作用几乎和你自己写的一样,但是有一个微妙的区别

keepWhen : Signal Bool -> a -> Signal a -> Signal a
keepWhen boolSig a aSig =
  zip boolSig aSig
  |> sampleOn aSig
  |> keepIf fst (True, a)
  |> map snd
zip只是一个Signal.map2,用于组合这两个信号。keepIf是Signal.filter的一个更清晰的旧名称。所以基本上都是一样的。但是在将两个信号压缩在一起之后,就有了一个样本。就是这样,过滤的结果是一个信号,它只在原始值信号aSig更新时更新,而在boolSig更新时不更新

替代语义学 还有另一个过滤器名为:信号布尔->a->信号a->信号a,其描述如下:

Signal.sampleOn和keepWhen的组合。当 第一个信号变为真,即第二个信号的最新值 将被传播

此选项与您编写的代码匹配,但与您的描述不匹配。只有当鼠标按钮按下时,其值才会更改

现在,由您来确定您真正想要的行为:

库函数 有一个名为“完全公开”的信号实用程序库:我是该库的作者,该库有一个函数用于以下内容::Signal Bool->a->Signal a->Signal a

[…]过滤器,只要信号布尔值为真,它就会保留来自信号a的事件

实施 如果你想知道的话,它的作用几乎和你自己写的一样,但是有一个微妙的区别

keepWhen : Signal Bool -> a -> Signal a -> Signal a
keepWhen boolSig a aSig =
  zip boolSig aSig
  |> sampleOn aSig
  |> keepIf fst (True, a)
  |> map snd
zip只是一个Signal.map2,用于组合这两个信号。keepIf是Signal.filter的一个更清晰的旧名称。所以基本上都是一样的。但是在将两个信号压缩在一起之后,就有了一个样本。就是这样,过滤的结果是一个信号,它只在原始值信号aSig更新时更新,而在boolSig更新时不更新

替代语义学 还有另一个过滤器名为:信号布尔->a->信号a->信号a,其描述如下:

Signal.sampleOn和keepWhen的组合。当 第一个信号变为真,即第二个信号的最新值 将被传播

此选项与您编写的代码匹配,但与您的描述不匹配。只有当鼠标按钮按下时,其值才会更改


现在由您来决定您真正想要的行为:

谢谢!你说得对,我的描述有点不准确,我已经更新了。现在一起处理isDown和position更新是一种权宜之计,这样我的解决方案和示例就可以很好地工作了。在某个时候,我会单独处理isDown更新,所以我会使用keepWhen,或者将sampleOn添加到我的函数中。谢谢!你说得对,我的描述有点不准确,我已经更新了。现在一起处理isDown和position更新是一种权宜之计,这样我的解决方案和示例就可以很好地工作了。在某个时刻,我将单独处理isDown更新,因此我将使用keepWhen,或者将sampleOn添加到我的函数中。