从列表中创建信号

时间:2015-07-26 21:24:47

标签: elm elm-signal

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

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

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

2 个答案:

答案 0 :(得分: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]。这应该使您能够在输入xyz之后查看程序的状态。

答案 1 :(得分:2)

我不认为在纯榆树中有任何方法可以同步(Apanatshka的答案很好地说明了如何跨时间设置一系列事件为什么这是一个坏主意)。如果我们看一下大多数信号的定义方式,我们会看到它们在某些时候都会进入本机包。

然后问题变成:我们可以本地吗?

f : List a -> Signal a

我经常认为(信号a)是随时间变化的a。在这里,我们提供了一个列表as,并希望它能够随着时间的推移而改变我们。

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

让我们说我们用我们的列表来到达本土。我们想要一些类似于Signal.constant的东西,但是有一些额外的行为会发送&#39;每一个后来。我们什么时候可以发送?我猜我们在信号构建功能期间无法做到这一点,因为我们仍在构建信号图。这给我们留下了其他几个选择:

  • 与setTimeout有点令人发指的是,安排发送每个&#39; a&#39;在未来的适当时候
  • 将钩子设计到elm运行时,以便我们可以在信号图完全构造时运行任意回调

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

对于测试,你建议使用List折叠模仿foldp的行为将是我的方式。