Haskell - 列表列表中的元素组合列表
Haskell - List of combinations of elements from list of lists
假设我有一些列表列表 [[a, b], [c], [d, e, f], ...]
,其中列表中的列表可以是任意长度。我已经对列表进行排序,使最短的列表排在第一位,并且我想生成列表中所有元素组合的列表,以便我得到一个列表 [[a, c, d, ...], [a, c, e, ...], [a, c, f, ...], [b, c, d, ...], ...]
,即组合是通过更改元素生成的首先从最后的列表中选择,向上移动列表以更改类似于计数的元素。
使用这个列表,我将让列表的头部使用惰性求值,因为我只需要 1 个满足谓词的列表。如何生成列表?
是的,这是sequenceA :: (Applicative f, Traversable t) => t (f a) -> f (t a)
的特例:
Prelude> sequenceA ["ab", "c", "def"]
["acd","ace","acf","bcd","bce","bcf"]
这里以f ~ []
、t ~ []
、a ~ Char
为例。 SequenceA
在这里等同于:
-- sequenceA for f ~ [] and t ~ []
sequenceAList [] = [[]]
sequenceAList (c:cs) = (:) <$> c <*> sequenceAList cs
对于单个项目 sequenceA ["def"]
因此等同于:
sequenceA ["def"] = (:) <$> "def" <*> [[]]
因此采用 "def"
的所有元素、Char
角色 'd'
、'e'
和 'f'
,然后将其与所有元素组合列表 [[]]
(仅 []
),因此产生 "d"
、"e"
和 "f"
.
然后对于 sequenceA ["c", "def"]
它因此等同于:
sequenceA ["c", "def"] = (:) <$> "c" <*> ["d", "e", "f"]
因此产生:["cd", "ce", "cf"]
,最后:
sequenceA ["ab", "c", "def"] = (:) <$> "ab" <*> ["cd", "ce", "cf"]
将产生:
sequenceA ["ab", "c", "def"] = ["acd", "ace", "acf", "bcd", "bce", "bcf"]
你用列表理解标记了这个:
pCombs pred xs = take 1 [ ys | ys <- sequenceAL xs, pred ys]
sequenceAL (xs:t) = [ x : ys | x <- xs, ys <- sequenceAL t]
sequenceAL [] = [ [] ]
sequenceAL [xs] = [ [x] | x <- xs]
sequenceAL [xs,ys] = [ [x,y] | x <- xs, y <- ys]
sequenceAL [xs,ys,zs] = [ [x,y,z] | x <- xs, y <- ys, z <- zs]
--- ....
列表理解就像嵌套循环。
可以看出,sequenceAL
(sequenceA
专门用于列表,[]
)枚举其参数列表中所有序列的笛卡尔积(最后一个“旋转“ 最快的)。由于该列表的长度是任意的,因此元素被收集到列表中,而不是元组中。
我们还可以定义
sequenceAL (xs:t) = [ x : ys | ys <- sequenceAL t, x <- xs]
结果列表中的 第一个 元素旋转最快。枚举的顺序可能无关紧要,它可以帮助解决内存问题。有关更多信息,请参阅 。
此外,如果您的谓词可以应用于部分结果列表以提前清除某些列表,则应该这样做,将过滤与生成步骤结合起来,以减少枚举space.换句话说,尽早测试,以防止无用的枚举。
假设我有一些列表列表 [[a, b], [c], [d, e, f], ...]
,其中列表中的列表可以是任意长度。我已经对列表进行排序,使最短的列表排在第一位,并且我想生成列表中所有元素组合的列表,以便我得到一个列表 [[a, c, d, ...], [a, c, e, ...], [a, c, f, ...], [b, c, d, ...], ...]
,即组合是通过更改元素生成的首先从最后的列表中选择,向上移动列表以更改类似于计数的元素。
使用这个列表,我将让列表的头部使用惰性求值,因为我只需要 1 个满足谓词的列表。如何生成列表?
是的,这是sequenceA :: (Applicative f, Traversable t) => t (f a) -> f (t a)
的特例:
Prelude> sequenceA ["ab", "c", "def"]
["acd","ace","acf","bcd","bce","bcf"]
这里以f ~ []
、t ~ []
、a ~ Char
为例。 SequenceA
在这里等同于:
-- sequenceA for f ~ [] and t ~ []
sequenceAList [] = [[]]
sequenceAList (c:cs) = (:) <$> c <*> sequenceAList cs
对于单个项目 sequenceA ["def"]
因此等同于:
sequenceA ["def"] = (:) <$> "def" <*> [[]]
因此采用 "def"
的所有元素、Char
角色 'd'
、'e'
和 'f'
,然后将其与所有元素组合列表 [[]]
(仅 []
),因此产生 "d"
、"e"
和 "f"
.
然后对于 sequenceA ["c", "def"]
它因此等同于:
sequenceA ["c", "def"] = (:) <$> "c" <*> ["d", "e", "f"]
因此产生:["cd", "ce", "cf"]
,最后:
sequenceA ["ab", "c", "def"] = (:) <$> "ab" <*> ["cd", "ce", "cf"]
将产生:
sequenceA ["ab", "c", "def"] = ["acd", "ace", "acf", "bcd", "bce", "bcf"]
你用列表理解标记了这个:
pCombs pred xs = take 1 [ ys | ys <- sequenceAL xs, pred ys]
sequenceAL (xs:t) = [ x : ys | x <- xs, ys <- sequenceAL t]
sequenceAL [] = [ [] ]
sequenceAL [xs] = [ [x] | x <- xs]
sequenceAL [xs,ys] = [ [x,y] | x <- xs, y <- ys]
sequenceAL [xs,ys,zs] = [ [x,y,z] | x <- xs, y <- ys, z <- zs]
--- ....
列表理解就像嵌套循环。
可以看出,sequenceAL
(sequenceA
专门用于列表,[]
)枚举其参数列表中所有序列的笛卡尔积(最后一个“旋转“ 最快的)。由于该列表的长度是任意的,因此元素被收集到列表中,而不是元组中。
我们还可以定义
sequenceAL (xs:t) = [ x : ys | ys <- sequenceAL t, x <- xs]
结果列表中的 第一个 元素旋转最快。枚举的顺序可能无关紧要,它可以帮助解决内存问题。有关更多信息,请参阅
此外,如果您的谓词可以应用于部分结果列表以提前清除某些列表,则应该这样做,将过滤与生成步骤结合起来,以减少枚举space.换句话说,尽早测试,以防止无用的枚举。