【问题标题】:How does one create a set of 3-tuples in Elm meeting a given condition?如何在 Elm 中创建一组满足给定条件的 3 元组?
【发布时间】:2015-04-14 03:39:58
【问题描述】:

我知道 Elm 既没有 for 循环(不足为奇)也没有理解(有点令人惊讶)。我知道map 将用于人们可能期望理解的地方。

但是如何从三个范围变量构建一组 3 元组?我对生成这些元组很感兴趣,在 Python 中生成这些元组很简单:

>>> [(x,y,z) for z in range(5) for y in range(z) for x in range(y)]
[(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3), (0, 1, 4), (0, 2, 4), 
(1, 2, 4), (0, 3, 4), (1, 3, 4), (2, 3, 4)]

我不确定如何在 Elm 中制作它。这是我尝试过的:

import Text (asText)
import List (map)
main =
  asText <| map (\z -> map (\y -> map (\x -> (x,y,z)) [0..y-1]) [0..z-1]) [0..4]

这会产生

[[],[[]],[[],[(0,1,2)]],[[],[(0,1,3)],[(0,2,3),(1,2,3)]],
[[],[(0,1,4)],[(0,2,4),(1,2,4)],[(0,3,4),(1,3,4),(2,3,4)]]]

接近但需要展平。

我是 Elm 新手,所以我不知道生成这些元组的正确方法。我可能会弄清楚如何展平我想出的列表,代码本身似乎相当冗长(我应该使用List.map3 代替吗?)对于大数字范围,我想按需生成值。有没有办法将这些值生成为信号?

【问题讨论】:

    标签: signals elm


    【解决方案1】:

    扁平化

    使您的示例按照您想要的方式工作的最小更改是将外部两个 map 更改为 concatMap

    import Text (asText)
    import List (map,concatMap)
    main =
      asText <| concatMap (\z -> concatMap (\y -> map (\x -> (x,y,z)) [0..y-1]) [0..z-1]) [0..4]
    

    根据你喜欢阅读代码的方式,你可能更喜欢这个:

    import Text (asText)
    import List (map,concatMap)
    
    list = 
      [0..4] |> concatMap (\z -> 
        [0..z-1] |> concatMap (\y -> 
          [0..y-1] |> map (\x -> (x,y,z))))
    
    main =
      asText list
    

    这实际上不是你可以用map3 做的事情,因为这只适用于不相互依赖的列表。

    按需生成

    信号可能不适合按需生成。除非涉及明显的时间成分,即使列表结束信号也不是正确的选择。

    要生成一些东西,您应该定义一个惰性序列。你可以使用函数来模拟惰性,或者如果你想记住惰性动作,可以使用Lazy library

    要创建您自己的惰性序列,只需使用以下内容:

    type LazySeq a = End | Item a (() -> LazySeq a)
    
    map : (a -> b) -> LazySeq a -> LazySeq b
    map f ls =
      case ls of
        End -> End
        Item i next -> Item (f i) (\() -> map f (next ()))
    
    append : LazySeq a -> LazySeq a -> LazySeq a
    append l r =
      case l of
        End -> r
        Item i next -> Item i (\() -> append (next ()) r)
    
    concat : LazySeq (LazySeq a) -> LazySeq a
    concat ls =
      case ls of
        End -> End
        Item i next ->
          case i of
            End -> concat (next ())
            Item i2 next2 -> Item i2 (\() -> append (next2 ()) (concat (next ())))
    
    concatMap : (a -> LazySeq b) -> LazySeq a -> LazySeq b
    concatMap f ls =
      concat (map f ls)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 2018-05-04
      • 2014-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-22
      相关资源
      最近更新 更多