【发布时间】:2018-05-08 15:08:59
【问题描述】:
Haskell 中是否有任何函数或方法可以帮助我获取元组列表,例如[(1,2),(3,4),(5,6)] 和
返回 [1,2,3,4,5,6] 并使用列表理解?
我正在专门寻找一个带有参数xs 和
的函数
在(函数的)主体中有一个列表理解。
【问题讨论】:
标签: list haskell list-comprehension
Haskell 中是否有任何函数或方法可以帮助我获取元组列表,例如[(1,2),(3,4),(5,6)] 和
返回 [1,2,3,4,5,6] 并使用列表理解?
我正在专门寻找一个带有参数xs 和
的函数
在(函数的)主体中有一个列表理解。
【问题讨论】:
标签: list haskell list-comprehension
给定元组列表名为ts,我们可以执行两次迭代:
[ t | (a, b) <- ts, t <- [a, b] ]
所以这里我们首先遍历ts 中的元组(a, b),接下来我们构造一个新列表[a, b],我们也遍历该列表,我们为每个t 生成t [a, b].
或者使用无点列表单子:
(>>= uncurry ((. pure) . (:)))
【讨论】:
(uncurry (:) . second (:[]) =<<):“将第一个元素放在第二个元素上,每个元素都包含在一个列表中”。 (second 来自Control.Arrow,在这种情况下可以替换为fmap。)
当然,您可以处理任何列表,甚至是列表推导式中的元组列表。不同的是形式。您在之前的两个很好的答案中看到,形式是(a,b)或(x,y)。这两个意思是一样的。它们表示元组中的两个元素。处理元组形式的问题是输出是单独的,两个项目列表。这就是为什么concat 如此有价值的原因。
我非常喜欢列表推导式,上面给出了使用列表推导式展平任何类型列表的经典形式。
我对 Haskell 比较陌生,无法理解 folds 如何生成一个列表,而不是像 sum 或 product 这样的单个值。
这样的问题非常宝贵,因为它们可以帮助我理解。
foldr 版本会生成一个列表。你想要的清单。为什么它是一个列表而不是单个值?这是因为foldr 产生了一系列越来越大的列表,最后一个最大的就是答案。
这是一个 foldr 版本的函数,用于展平元组列表。
foldr (\(a,b) l-> a:b:l) [] [(1,2),(3,4),(5,6)]
[1,2,3,4,5,6]
【讨论】:
concatMap (\(x, y) -> [x, y]) [(1,2),(3,4),(5,6)]
会给
[1,2,3,4,5,6]
如果你不想使用concatMap,你可以这样做
concat . map (\(x, y) -> [x, y])
【讨论】:
concatMap 在Data.Foldable 中定义,因此必须是imported。 concat.map 不导入也一样。