2

是否可以Signal从 a 创建 a List?基本上我想要的是带有签名的东西List a -> Signal a。我知道 aSignal代表一个随时间变化的值,所以这样的事情实际上没有任何意义(即我想不出在生产代码中使用它的理由)。

我可以看到它的应用程序进行测试。例如,假设某个函数依赖于 a 的过去值Signal(例如 via foldp),并且您想在信号已接收到值 x、y 和 z 的情况下对系统状态进行断言。

Signal请注意,表示它只会接收固定数量的值不必有什么特别之处。我认为它更像是:在生产中,您有一次Signal鼠标点击,并且您想从给定的起始位置测试它,在给定的一组点击之后,系统应该处于其他一些已知状态。我知道你可以通过调用函数固定次数并用新值反馈结果来模拟这一点,我只是想知道这是否可能。

4

2 回答 2

3

我想这是可能的。您使用基于时间的信号,并将列表中的值映射到它上面:

import Time
import Graphics.Element exposing (show)

list = [1..10]


signalFromList : List a -> Signal a
signalFromList list =
  let
    (Just h) =
      List.head list

    time =
      Time.every Time.second

    maybeFlatMap =
      flip Maybe.andThen

    lists =
      Signal.foldp (always <| maybeFlatMap List.tail) (Just list) time
  in
    Signal.filterMap (maybeFlatMap List.head) h lists

main = Signal.map show <| signalFromList list

然而!

在没有信号的情况下进行测试应该不难。如果你有foldp某个地方,在测试中你可以使用List.foldl一个列表[x,y,z]来代替。x这应该使您能够在输入, y,之后查看程序的状态z

于 2015-07-26T22:10:01.797 回答
2

我认为没有任何方法可以在纯榆树中同步完成(Apanatshka 的回答很好地说明了如何跨时间设置一系列事件以及为什么这是一个坏主意)。如果我们看看大多数信号是如何定义的,我们会看到它们在某个时候都归结为原生包。

那么问题就变成了:我们可以原生地做到这一点

f : List a -> Signal a

我经常将 (Signal a) 视为“随时间变化的 a”。在这里,我们提供了一个 as 的列表,并希望该函数为我们使其随时间而变化。

在我们继续之前,我建议快速浏览一下 Native/Signal.js:https ://github.com/elm-lang/core/blob/master/src/Native/Signal.js

假设我们带着我们的列表来到了本土。我们想要一些有点像 Signal.constant 的东西,但有一些额外的行为,之后会“发送”每个 a。不过,我们什么时候可以发送?我猜我们不能在信号构造函数期间这样做,因为我们仍在构建信号图。这给我们留下了其他几个选择:

  • setTimeout 令人发指的事情,将每个“a”安排在未来的适当时间发送
  • 在 elm 运行时中设计一个钩子,以便我们可以在信号图完全构建时运行任意回调

至少对我来说,前者听起来容易出错,我希望后者不存在(而且永远不会存在)!

对于测试,您建议使用 List fold 来模仿 foldp 的行为,这就是我的做法。

于 2015-07-26T22:15:22.813 回答