Конкатенация списков в Haskell - PullRequest
5 голосов
/ 14 марта 2012

Мне нужна функция, которая принимает два списка любого типа и возвращает один (т.е. f:: [[a]] -> [[a]] -> [[a]]). По сути, тоже производим «объединение» двух списков ввода.

, например

> f [[1,2,3], [123]] [[4,5,6], [3,7]]
[[1,2,3,4,5,6], [1,2,3,3,7], [123,4,5,6], [123,3,7]]

У меня сейчас так далеко с этим:

f _ [] = []
f [] _ = []
f (xs:xss) (ys:yss) = ((xs ++ ys) : [m | m <- f [xs] yss])

Но это не учитывает xss и неправильно. Есть предложения?

Ответы [ 5 ]

9 голосов
/ 14 марта 2012

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

Prelude> let xs = [[1,2,3], [123]]
Prelude> let ys = [[4,5,6], [3,7]]
Prelude> [x ++ y | x <- xs, y <- ys]
[[1,2,3,4,5,6],[1,2,3,3,7],[123,4,5,6],[123,3,7]]
3 голосов
/ 14 марта 2012
f l1 l2 = [x ++ y | x <- l1, y <- l2]
3 голосов
/ 14 марта 2012
import Control.Applicative

(++) <$> [[1,2,3], [123]] <*> [[4,5,6], [3,7]]
[[1,2,3,4,5,6],[1,2,3,3,7],[123,4,5,6],[123,3,7]]
2 голосов
/ 14 марта 2012

In Alternative:

import Control.Applicative

f :: (Applicative f, Alternative g) => f (g a) -> f (g a) -> f (g a)
f = liftA2 (<|>)
1 голос
/ 14 марта 2012
f a b = map concat . sequence $ [a,b]

Масштабируется для объединения любого количества списков.

...