生成所有符号的变化

时间:2018-03-03 17:11:47

标签: haskell transform combinations

我有很多名单。简称[[1,2],[3,4]]。 我需要生成每个元素的所有符号变化。因此,对于简短的例子,结果将是

[[1,2],[3,4],[-1,2],[1,-2],[-1,-2],[-3,4],[3,-4],[-3,-4]]

是否有包执行此类操作?否则我可以使用什么算法? (我承认我没有想过很多......)。

这可以提供帮助,我的所有列表都有相同的长度。

修改

嗯......也许是这样的想法:

x = [[2*i,2*j] | i <- [1, -1], j <- [-1,1]]
x
[[2,-2],[2,2],[-2,-2],[-2,2]]

2 个答案:

答案 0 :(得分:6)

问题可以分解为两个步骤:

  1. 对于给定的数字列表,生成所有可能的符号
  2. 对于列表列表,将(1)中的函数应用于每个列表,然后连结结果。
  3. 对于1.您可以编写一个简单的递归函数,首先处理列表的尾部,然后对于每个结果组合,它为这两个符号生成两个版本。

    signs :: [Int] -> [[Int]]
    signs [] = [[]]
    signs (x : xs)
      = let ps = signs xs
        in map (x :) ps ++ map ((-x) :) ps
    

    对于2.只需将signs函数映射到输入上,然后将它们连接起来。这就是concatMap函数的作用:

    signsAll :: [[Int]] -> [[Int]]
    signsAll = concatMap signs
    

答案 1 :(得分:4)

我试图在这里使用一个应用程序,因为它看起来像你几乎在那里

[id,negate] <*> [3,4]

但事实证明我需要sequencemap,在这种情况下,可以合并为traverse

traverse (\x->[x,-x]) [3,4]
[[3,4],[3,-4],[-3,4],[-3,-4]]

正如其他人所提到的,现在你的功能需要concatMap

concatMap (traverse (\x->[x,-x])) [[3,4],[1,2]]
[[3,4],[3,-4],[-3,4],[-3,-4],[1,2],[1,-2],[-1,2],[-1,-2]]