2012-03-13 75 views
5

我想要一个带有两个任意类型列表并返回一个(即f:: [[a]] -> [[a]] -> [[a]])的函数。基本上,也会产生两个输入列表的“连接”。Haskell中列表的连接

例如

> 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和是错误的。有什么建议么?

回答

9

这是一个笛卡儿的产品,所以你可以简单地使用一个列表理解来做所有事情。

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
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]] 
+10

或只是'liftA2(++)' – luqui 2012-03-13 22:14:54

3
f l1 l2 = [x ++ y | x <- l1, y <- l2] 
+0

我怎么错过了这个!?!踢自己。基本的基本东西! – 2012-03-13 21:57:24

2

Alternative

import Control.Applicative 

f :: (Applicative f, Alternative g) => f (g a) -> f (g a) -> f (g a) 
f = liftA2 (<|>) 
1
f a b = map concat . sequence $ [a,b] 

秤弥补组合任意数量的列表。