Haskell中两个列表的元素的所有组合

时间:2015-08-19 11:14:03

标签: list haskell tuples combinations

鉴于两个列表[a, b][c, d],我希望得到以下结果:

[(a,c), (a,d), (b,c), (b,d)]

我如何在Haskell中执行此操作?是否有内置功能,或者我应该自己实现?

5 个答案:

答案 0 :(得分:25)

[ (x,y) | x<-[a,b], y<-[c,d] ]

这并不需要任何进一步的解释,是吗?

答案 1 :(得分:15)

一直以来的应用风格!

λ> :m + Control.Applicative
λ> (,) <$> ['a','b'] <*> ['c','d']
[('a','c'),('a','d'),('b','c'),('b','d')]

(我已经避开上面的任何String句法糖,以便与你的榜样保持接近。)

有关信息,(,)是一个函数的特殊语法,它接受两个参数并从中生成一对:

λ> :t (,)
(,) :: a -> b -> (a, b)

修改:正如leftaroundabout中的his comment所述,您也可以使用liftA2

λ> :m + Control.Applicative
λ> let combine = liftA2 (,)
λ> combine "ab" "cd"
[('a','c'),('a','d'),('b','c'),('b','d')]

答案 2 :(得分:9)

如何在命令式伪代码中执行此操作?

for each element x in [a,b]:
    for each element y in [c,d]:
        produce (x,y)

在Haskell中,这写为

outerProduct xs ys =
   do
       x <- xs          -- for each x drawn from xs:
       y <- ys          --   for each y drawn from ys:
       return (x,y)     --      produce the (x,y) pair

(左下方的评论)这当然非常接近于如何定义this monadic组合子,所以实际上

outerProduct = liftM2 (,)

liftA2 (,)相同,并根据列表推导,concatMap函数,>>=<$><*>进行各种重写运营商。

从概念上讲,这是Applicative的内容 - 更好地命名为Pairing, - 因为这两个&#34;容器&#34;的元素配对/&#34;运营商&#34; /无论什么正是Applicative Functor的意思。恰好Haskell的do符号适用于monad,而不是( yet liftM2

在某种意义上编译时嵌套循环 Applicative / Pairing仿函数; Monads添加了动态创建嵌套循环的功能,具体取决于&#34;外部&#34;列举。

答案 3 :(得分:8)

最直观的是使用列表理解,其他aproaches包括使用applicative functor:

(,) <$> [1,2,3] <*> [4,5,6]

这是做什么的?

请记住(,) :: a -> b -> (a, b)使用两个参数并返回一个元组。

<$>是实际的fmap,(<$>) :: Functor f => (a -> b) -> f a -> f b 它需要一个功能并提升它。在这种情况下,它需要(,)并将其提升到列表中。因此let x = (,) <$> [1,2]将生成x :: [b -> (Integer, b)],它是采用b的函数列表,并返回带有一个固定参数(整数,b)的元组。最后,我们使用<*>应用它来生成所有组合。

答案 4 :(得分:5)

使用列表理解:

s = [a,b]
s' = [c,d]

all_combinations = [(x,y) | x <- s, y <- s']