【问题标题】:How do I merge signals in Helm?如何在 Helm 中合并信号?
【发布时间】:2015-08-13 17:24:47
【问题描述】:

我正在使用基于 Elm 语言的Helm 进行项目。

我需要根据一对信号中的哪个信号首先到达来触发一个事件。在 Elm 中,我会使用 merge 函数,但在 Helm 中找不到等效函数。我看到的最接近的是组合(在信号库中),它似乎没有做我想要的。似乎 combine 只是获取一个信号列表并将它们直接转换为列表信号,这并不是我想要的。

编辑:具体来说,我正在寻找一个带有签名 Signal a -> Signal a -> Signal a 的函数,该函数将第一个信号触发并丢弃第二个信号。

在 Helm 中完成此任务的最佳方法是什么?

【问题讨论】:

    标签: haskell frp elm


    【解决方案1】:

    您可以使用Applicative 实例组合事物。例如liftA2 (,) 的类型为Signal a -> Signal b -> Signal (a,b)。

    (不过,我不能 100% 确定这是否是您的问题。如果您的问题是关于合并像 Event a -> Event a -> Event a 这样的事件,我不确定 helm 是否具有这样的功能。我只能找到有关行为的文档- 像具有连续语义的 Signals。)

    【讨论】:

    • 是的,我问的是像signal a -> signal a -> signal a这样的合并事件。具体来说,我希望行为接受第一个触发的信号并丢弃另一个。但是,谢谢你,一旦我有足够的声誉,我会为你投票。
    • 当然,很抱歉,我无法提供更多帮助。在 netwire 中它是 hackage.haskell.org/package/netwire-5.0.1/docs/… 但我在 helm 中没有看到任何类似的东西。
    【解决方案2】:

    我认为最好的方法是找出 Helm 的 Signals 是如何用 Elerea 的东西来实现的,并以那些更原始的术语来实现 merge。恐怕我帮不了你,因为我不太了解 Helm,而且我根本不了解 Elerea。

    我可以为您提供仅基于 Helm 的 hacky 解决方案。您可以使用timestamp 来区分压缩信号中的不同事件:

    merge sigL sigR =
      let
        tsMerge (t1,v1) (t2,v2) =
            if t1 >= t2
              then v1
              else v2
      in
        tsMerge <~ timestamp sigL ~~ timestamp sigR
    

    【讨论】:

    • 由于某种原因,这最终不能很好地工作。它在不同的机器上有所不同:我在一台 linux 计算机上尝试过,它运行良好,但是当我在 linux 虚拟机上尝试它时,它什么也没发生。我修复它的方式是一个 hacky 合并,它基本上每次都用lift2 获取我想要占上风的信号。
    • 奇怪的是每台机器的行为不同,这对我来说听起来像是一个错误......我不明白你如何用lift2制作merge,你是怎么做到的?
    • 我确定这是一个错误。不过,我不得不在虚拟机上展示我的项目,所以不得不做一个工作。我认为自从 Helm 人尝试了一个 monoid 实现。我敢肯定这也有点错误。我想我以后会坚持使用 Elm。
    猜你喜欢
    • 1970-01-01
    • 2022-11-02
    • 2015-03-07
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    相关资源
    最近更新 更多