【问题标题】:list of tuples into list with list comprehension使用列表理解将元组列表放入列表中
【发布时间】:2018-05-08 15:08:59
【问题描述】:

Haskell 中是否有任何函数或方法可以帮助我获取元组列表,例如[(1,2),(3,4),(5,6)]
返回 [1,2,3,4,5,6] 并使用列表理解?

我正在专门寻找一个带有参数xs
的函数 在(函数的)主体中有一个列表理解。

【问题讨论】:

标签: list haskell list-comprehension


【解决方案1】:

给定元组列表名为ts,我们可以执行两次迭代:

[ t | (a, b) <- ts, t <- [a, b] ]

所以这里我们首先遍历ts 中的元组(a, b),接下来我们构造一个新列表[a, b],我们也遍历该列表,我们为每个t 生成t [a, b].

或者使用无点列表单子:

(>>= uncurry ((. pure) . (:)))

【讨论】:

  • 顺便说一下,无点版本会更清晰,如(uncurry (:) . second (:[]) =&lt;&lt;):“将第一个元素放在第二个元素上,每个元素都包含在一个列表中”。 (second 来自Control.Arrow,在这种情况下可以替换为fmap。)
【解决方案2】:

当然,您可以处理任何列表,甚至是列表推导式中的元组列表。不同的是形式。您在之前的两个很好的答案中看到,形式是(a,b)或(x,y)。这两个意思是一样的。它们表示元组中的两个元素。处理元组形式的问题是输出是单独的,两个项目列表。这就是为什么concat 如此有价值的原因。

我非常喜欢列表推导式,上面给出了使用列表推导式展平任何类型列表的经典形式。

我对 Haskell 比较陌生,无法理解 folds 如何生成一个列表,而不是像 sumproduct 这样的单个值。

这样的问题非常宝贵,因为它们可以帮助我理解。

foldr 版本会生成一个列表。你想要的清单。为什么它是一个列表而不是单个值?这是因为foldr 产生了一系列越来越大的列表,最后一个最大的就是答案。

这是一个 foldr 版本的函数,用于展平元组列表。

foldr (\(a,b) l-> a:b:l) []    [(1,2),(3,4),(5,6)]

[1,2,3,4,5,6]

【讨论】:

    【解决方案3】:
    concatMap (\(x, y) -> [x, y]) [(1,2),(3,4),(5,6)]
    

    会给

    [1,2,3,4,5,6]
    

    如果你不想使用concatMap,你可以这样做

    concat . map (\(x, y) -> [x, y])
    

    【讨论】:

    • concatMapData.Foldable 中定义,因此必须是importedconcat.map 不导入也一样。
    • @fpmora Hoogle 说它也在基础前奏中
    • 我的错。我以为不是。很高兴知道,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多