通过另一个信号的值过滤信号

时间:2015-11-28 20:45:29

标签: elm

我想为鼠标位置创建一个过滤的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))

3 个答案:

答案 0 :(得分:2)

我更喜欢@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)

答案 1 :(得分:2)

库函数

有一个名为signal-extra的信号的实用程序库(完全披露:我是该库的作者),它具有以下功能:keepWhen : Signal Bool -> a -> Signal a -> Signal a

  

[...]过滤器,只要Signal a为真,就会保留Signal Bool的事件。

实施

如果您想知道,implementation几乎和您自己写的一样,但有一个微妙的区别!

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 (,)来组合这两个信号。 keepIfSignal.filter的旧名称(IMHO清除程序)。所以这一切都基本相同。但是在将两个信号压缩在一起之后,有一个sampleOn。因此,过滤的结果是仅在原始值信号aSig更新时更新的信号,并且在boolSig更新时不更新。

替代语义

还有另一个名为sampleWhen : Signal Bool -> a -> Signal a -> Signal a的过滤器,其中包含以下描述:

  

Signal.sampleOnkeepWhen的组合。当。。。的时候   第一个信号变为True,即第二个信号的最新值   将被传播。

此备选方案与您编写的代码匹配,但它与您的描述不匹配"只有当鼠标按钮关闭时,它的值才会发生变化"。

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

答案 2 :(得分:1)

在发布问题的同时,我找到了如何避免匿名功能。不过,我觉得有更优雅的解决方案。

function standardfunction() {

  var Type1 = document.getElementById('Standard').value;
  var adult = document.getElementById('adult').value;
  var child = document.getElementById('child').value;


  var Total_Cost
  var Type1 = 6
  var adult = 1
  var child = 0.5

  alert(Total_Cost = adult * Type1);

}

function firstclassfunction() {

  var Type2 = document.getElementById('First-Class').value;
  var adult = document.getElementById('adult').value;
  var child = document.getElementById('child').value;

  var Total_Cost
  var Type2 = 10
  var adult = 1
  var child = 0.5
  alert(Total_Cost = adult * Type2);

}