【问题标题】:Haskell algorithm for sequence of tuples in a list of lists用于列表列表中元组序列的 Haskell 算法
【发布时间】:2026-02-01 02:00:01
【问题描述】:

我在 Haskell 中玩了一下以熟悉它,但遇到了以下问题:

我想定义一个函数,给定一个包含一些其他列表的列表,每个列表包含 0 个或多个元组,创建一个新列表,如下所示:

*Main> foo 
    [
      [ (1,2), (3,4)  ],
      [ (5,6)         ],
      [ (7,8), (9,10) ]
    ]


  = [
      [ (1,2), (5,6), (7,8)  ],
      [ (1,2), (5,6), (9,10) ],
      [ (3,4), (5,6), (7,8)  ],
      [ (3,4), (5,6), (9,10) ]
    ]

因此,换句话说,该函数应该组成一个列表,其中第一个列表中的每个元组与每种情况下剩余 N 个列表中的其他元组之一相结合。

我试图为此编写一个递归算法,但无法集中精力处理 N 数量的其他列表来组合元组。对于两个元组列表,我会写如下内容:

composeList [] _        = []
composeList (x:xs) list = composeTuples x list ++ composeList xs list

composeTuples _ []     = []
composeTuples t (x:xs) = [t,x] : composeTuples t xs

这给了我:

*Main Data.List> composeList [(1,2),(3,4)] [(5,6),(7,8)]

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

虽然我似乎无法将这些部分放在一起并使其适用于任意数量的列表,每个列表都有任意 (>=0) 个元组。

我都对使用 Haskell 的一些预定义函数(如果可能)以及与我在上面示例中所采用的方法有些相似的方法来解决这个问题感兴趣。

提前致谢!

【问题讨论】:

    标签: list haskell recursion


    【解决方案1】:

    这只是列表单子,不确定地从每个列表中选择一个元素。

    你要找的函数是sequence :: Monad m => [m a] -> m [a] from Control.Monad

    λ. let as = [(1,2),(3,4)]
    λ. let bs = [(5,6)]
    λ. let cs = [(7,8),(9,10)]
    λ. let xss = [as, bs, cs]
    λ. sequence xss
      [[(1,2),(5,6),(7,8)]
      ,[(1,2),(5,6),(9,10)]
      ,[(3,4),(5,6),(7,8)]
      ,[(3,4),(5,6),(9,10)]
      ]
    

    【讨论】:

      【解决方案2】:

      这是一个递归解决方案

      solution :: [[a]] -> [[a]]
      solution (x: xs) = [y: ys | y <- x, ys <- solution xs]
      solution []      = [[]]
      

      解决方案背后的想法如下:将列表头部的每个元素添加到您从递归计算输入列表尾部的结果中获得的每个列表中。

      【讨论】:

      • 应该是ys &lt;- solution xs
      最近更新 更多