【问题标题】:All combinations of elements of N lists in Haskell [duplicate]Haskell中N个列表的所有元素组合[重复]
【发布时间】:2021-04-22 02:52:06
【问题描述】:

为了合并两个列表,可以使用以下代码。

[(x,y) | x <- [1, 2, 3], y <- [4, 5, 6]]

或者

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

哪些产品

[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]

如果给定 N 个列表而不是 2 个列表,它们将以这种方式组合在一起,如何做到这一点?

如果可能的话,最好使用列表理解,因为我发现它最容易解释。

【问题讨论】:

  • 我认为你必须使用[[Int]] 而不是[(Int, Int)]
  • @user 我不确定我是否理解你的意思,抱歉我是haskell的新手
  • 如果你想把它推广到 N 个列表,你将不能使用元组,因为你不能只向一个元组添加一个元素,所以你需要列表。不过,您也许可以创建自己的类似元组的构造,您可以轻松地进行 cons 和 uncons 操作。 (顺便说一下,这是一个笛卡尔积)

标签: list haskell functional-programming list-comprehension combinatorics


【解决方案1】:

sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) 这样做:

> sequence [[1,2,3] , [4,5,6]]
[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]

> sequence [[1,2,3] , [4,5,6] , [7]]
[[1,4,7],[1,5,7],[1,6,7],[2,4,7],[2,5,7],[2,6,7],[3,4,7],[3,5,7],[3,6,7]]

Haskell 中没有任意长度的元组,因此必须使用 lists 来收集生成的“元组”。

sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)这里其实就够了,但是list的applicative functors和monads是一样的,所以没关系。

如果任何列表可能是无限的,如果需要更公平的枚举,则必须采用某种对角化方案(参见例如Cartesian product of infinite lists in Haskell 等)。

要自己实现,必须使用递归,

ncart :: [[a]] -> [[a]]
ncart (xs:t) = [ x:r | x <- xs, r <- ncart t]
ncart []     = [[]]

(但请参阅haskell running out of memory with finite lists 进行重要讨论)。

【讨论】:

    猜你喜欢
    • 2015-11-12
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 2018-03-11
    相关资源
    最近更新 更多