Haskell 生成所有符号的更改

Haskell 生成所有符号的更改,haskell,transform,combinations,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

我有很多清单。简而言之,
[[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]]

x=[[2*i,2*j]|i问题可分为两个步骤:

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

    signs :: [Int] -> [[Int]]
    signs [] = [[]]
    signs (x : xs)
      = let ps = signs xs
        in map (x :) ps ++ map ((-x) :) ps
    
    对于2.只需将
    符号
    函数映射到输入上,并对其进行压缩。这就是
    压缩映射
    函数的作用:

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

    我试着在这里使用一个应用程序,因为看起来你就快到了

    [id,negate] <*> [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]]
    

    您的示例中似乎缺少[1,-2]和[3,-4]您自己尝试过什么吗?此外,我也不太清楚为什么输出的类型是
    [[n]]
    ,而不是
    [[n]]]
    。子列表是否总是长度为2?您是对的@Axnyff,它们丢失了。这看起来像是两个操作:1)为单个列表生成所有可能的符号变化。2)将#1的操作应用于输入列表并收集结果。操作#2是
    映射
    /
    concatMap
    。看起来不错。非常感谢。我会的我测试我的真实案例,以后一定会投票并接受。
    signs=mapM(\x->[x,-x])
    你的代码Csongor有一个问题:0的案例。
    signsAll[[0,2],[2,3][[0,2],[0,-2],[0,2],[0,-2],[2,3],-2,3]]
    。你看到重复的了吗?我今晚太累了,没法解决这个问题。@DanielWagner,这是零问题。@nielwagner,没问题,
    signs=mapM(\x->nub[x,-x])
    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]]