Haskell - 每个矩阵中每个元素之间差异的总和

Sch*_*ron 2 haskell iterator loops sum matrix

我是Haskell的新手(以及一般的函数式编程),我正在尝试编写一个名为"profileDistance m1 m2"的函数,该函数将两个矩阵作为参数,需要计算每个矩阵中每个元素之间差异的总和.我可能没有那么好解释.让我来表现一下吧.

矩阵的形式为:[[(Char,Int)]] 每个矩阵可能看起来像这样:

m1 = [[('A',1),('A',2)],
      [('B',3),('B',4)],   
      [('C',5),('C',6)]]

m2 = [[('A',7),('A',8)],
      [('B',9),('B',10)],   
      [('C',11),('C',12)]]
Run Code Online (Sandbox Code Playgroud)

(注意:我在这个例子中按顺序编写了数字,但它们可以是任何顺序的任何数字.但是每个矩阵中每行的字符将匹配如示例中所示.)

结果(在上面的例子中)看起来像(伪代码):

result = ((snd m1['A'][0])-(snd m2['A'][0]))+((snd m1['A'][1])-(snd m2['A'][1]))+((snd m1['B'][0])-(snd m2['B'][0]))+((snd m1['B'][1])-(snd m2['B'][1]))+((snd m1['C'][0])-(snd m2['C'][0]))+((snd m1['C'][1])-(snd m2['C'][1]))
Run Code Online (Sandbox Code Playgroud)

这在任何具有for循环且无功能的语言中都很容易,但我不知道如何在Haskell中执行此操作.我有一种感觉功能map,fold或者sum会帮助我(不可否认,我不是100%肯定如何fold工作).我希望有一个简单的方法来做到这一点......请帮忙.

lar*_*sen 6

这里有一个建议:

solution m1 m2 = sum $ zipWith diffSnd flatM1 flatM2
  where
    diffSnd t1 t2 = snd t1 - snd t2
    flatM1 = concat m1
    flatM2 = concat m2
Run Code Online (Sandbox Code Playgroud)

我写了它,以便更容易理解构建块.基本思想是使用同时迭代我们的两个对列表zipWith.这里的类型:

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Run Code Online (Sandbox Code Playgroud)

这意味着它需要一个带有类型的函数a -> b -> c,一个列表a和一个列表b,并返回一个列表c.换句话说,zipWith在迭代的情况下,你只需要指定你想对迭代产生的每个项目做什么,在你的情况下将是一对(一个来自第一个矩阵,另一个来自第二个) .

传递的函数从每对中zipWith获取snd元素,并计算差异.回顾zipWith签名,您可以推断它将返回一个数字列表.所以我们需要做的最后一件事是使用函数对它们进行求和sum.

还有最后一个问题.实际上我们没有两个对的列表要传递给zipWith!,而是两个矩阵.我们需要在列表中"展平"它们,保留元素的顺序.这正是做什么的concat,因此在flatM1和的定义中对该函数的调用flatM2.

我建议你研究我提到的每个函数的实现,以便更好地掌握迭代是如何通过递归来表示的.HTH