如何从另一个列表构建列表,为原始列表中的每个元素创建多个元素?

时间:2011-11-10 04:40:48

标签: list haskell list-comprehension

我想做点什么

[(x, y, x+y) | (x,y) <- original]

但是,当然,这将返回类似的内容:

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

我想要的是:

[0, 0, 0, 0, 1, 1, 1, 1, 2]

我对Haskell很陌生,不熟悉它的习语。我怎样才能在Haskell中实现这个目标?

3 个答案:

答案 0 :(得分:7)

首先,对类型进行诽谤。您正在从名为(x,y)的列表中绘制对original。原始列表必须是original :: [(a,b)]对,例如[(1,6), (4,9)]。然后,为每个元素构造一个元组,从而得到元组列表的结果。我猜测你从来没有想过任何元组,但实际上希望列表中的一些元素由你的函数组合并将结果连接成一个新的列表。

您可能正在寻找concatMap功能:

> :t concatMap
concatMap :: (a -> [b]) -> [a] -> [b]
> concatMap (\x -> [x,x+1,x+7]) [1,2,3]
[1,2,8,2,3,9,3,4,10]

如果您确实想要同时使用两个(或更多)元素,那么有一些缺失的细节,例如,如果您有奇数个元素并且天气或不是元素重复,该怎么办(所以你看到{{ 1}}作为两个输入[1,2,3]1,2)。

如果元素重复,那么这只是2,3concatMap

zip

但如果你想把它们视为[1,2]和[3]那么你最好自己编写自己的函数:

> let ls = [1,2,3] in concatMap (\(x,y) -> [x,y,x+y]) (zip ls (drop 1 ls))
[1,2,3,2,3,5]

答案 1 :(得分:6)

看起来你只是做出了一个非确定性的选择 - 只是为了做出了哪些列表理解!

[v | (x,y) <- original, v <- [x, y, x+y]]

答案 2 :(得分:5)

您可以创建列表列表,然后使用concat展平它。

concat [[x, y, x+y] | (x, y) <- original]