Как создать список из другого списка, создав несколько элементов для каждого элемента в исходном списке? - PullRequest
2 голосов
/ 10 ноября 2011

Я хочу сделать что-то вроде

[(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?

Ответы [ 3 ]

7 голосов
/ 10 ноября 2011

Во-первых, диатриба по типам. Вы рисуете пару (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,2,3] как два входа 1,2 и 2,3).

Если элементы повторяются, то это просто concatMap и zip:

> 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,2] и [3], то лучше всего написать свою собственную функцию:

func [] = []
func [x] = [[x]] -- What do you want with the odd remaining element?
func (x:y:rest) = [x,y,x+y] : func rest

> concat (func [1,2,3])
[1,2,3,3]
6 голосов
/ 10 ноября 2011

Похоже, вы просто делаете недетерминированный выбор - для чего были созданы списочные понимания!

[v | (x,y) <- original, v <- [x, y, x+y]]
5 голосов
/ 10 ноября 2011

Например, вы можете создать список списков, а затем использовать concat, чтобы сгладить его.

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