在Haskell中构建列表推导内的列表列表

时间:2016-12-11 22:20:54

标签: algorithm haskell pattern-matching

我在wiki.haskell.org上找到了一种算法,用于生成给定列表中n个元素的组合。它通过列表理解来构造[[a]]

combos :: Int -> [a] -> [[a]]
combos 0 _  = [ [] ]
combos n xs = [ y:ys | y:xs' <- tails xs
                           , ys <- combos (n-1) xs']

假设我们执行combos 2 [1,2,3],那么主函数将如下所示:

combos 2 [1,2,3] = [ y:ys | y:xs' <- [[1,2,3],[2,3],[3],[]]
                           , ys <- combos 1 xs']

我认为在模式中y:xs' y是一个列表(第一次运行时为[1,2,3]),而xs'是一个列表列表([[2,3],[3],[]]第一次运行)。

当我将xs'作为递归combos调用(ys <- combos 1 xs')调用的参数抛出时,我对此部分感到困惑。combos现在变为[[a]] -> [[[a]]] }?)

这一切是如何运作的?请问您能描述一下这个功能是如何工作的吗?

1 个答案:

答案 0 :(得分:3)

请注意… <- …let … = …之间的区别。在列表理解中,x <- xs的两边不能具有相同的类型; x连续分配给xs的每个元素

在您的示例中,(y:xs') <- [[1,2,3],[2,3],[3],[]]表示我们从该列表中获取与模式(y:xs')匹配的元素。因此,我们第一次在此处进行选择,y == 1xs' == [2,3];我们第二次做出选择,y == 2xs' == [3],等等。