【问题标题】:Elm function with the type: Signal (List a) -> List (Signal a)Elm 函数类型为:Signal (List a) -> List (Signal a)
【发布时间】:2015-04-22 17:35:46
【问题描述】:

总的来说,我是 elm 和函数式编程的新手。但我使用的是 elm,我真的需要一个函数,它有一个 Signal(List String)作为输入并返回 List(Signal String)。

我知道我可能不应该在我的程序中使用更好的架构设计来解决这个问题,但是拥有一个可以做到这一点的函数将为我解决一个大问题。

combine 函数的作用正好相反:

combine : List (Signal a) -> Signal (List a)
combine = List.foldr (map2 (::)) (constant [])

我尝试做一些类似于 combine 功能的事情,但到目前为止都没有成功。关于如何创建这样的功能的任何想法?

【问题讨论】:

    标签: functional-programming elm


    【解决方案1】:

    这一般是不可能的

    combine 的倒数(通常)是不可能的。
    当您拥有一个静态大小的信号列表时,您可以将combine 它们转换为一个静态大小的信号列表。但是当你走另一条路时,不能保证信号中的列表是静态大小的。因此,您不能“仅仅”从中构造一个列表。
    (如果可以,那么List 类型的正常值可能会改变大小而不在类型周围显示Signal,并且您将在列表中动态创建和销毁信号。这是 Elm 不允许的两件事。)

    但有一些限制......

    当然,如果知道信号中的列表是静态大小的,你可以根据这个假设编写一个特定的函数;如果发生您对静态大小列表的假设错误的情况,该函数将在运行时失败。

    unsafe : Maybe a -> a
    unsafeHead m =
      case m of
        Just a -> a
        Nothing -> Debug.crash "unsafe: You're out of luck. The `Maybe` was not a `Just`. "
    
    uncombine : Int -> Signal (List a) -> List (Signal a)
    uncombine n sig =
      if n == 0
        then []
        else Signal.map (List.head >> unsafe) sig
          :: uncombine (n-1) (Signal.map (List.tail >> unsafe) sig)
    

    (我很确定这个问题在elm-discuss 邮件列表中讨论过一次,但我再也找不到了)

    【讨论】:

    • 感谢@Apanatshka 的回答。我知道列表需要是静态大小的,但是因为我很固执,所以我想继续尝试并将 uncombine 函数更改为:uncombine : Signal (List a) -> List (Signal a) uncombine sig = if (Signal.map isEmpty sig) then [] else Signal.map (List.head >> unsafe) sig :: uncombine (n-1) (Signal.map (List.tail >> unsafe) sig)。但我得到类型不匹配错误,因为 if 子句想要一个 Bool 值但得到 Signal Bool 值。这个问题有解决办法吗?
    • 不,没有解决方法。您正在尝试的事情是不可能的。
    猜你喜欢
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 2019-07-21
    • 2018-04-30
    • 2015-03-13
    相关资源
    最近更新 更多