Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops Haskell-每个矩阵中每个元素之间差异的总和_Loops_Haskell_Matrix_Iterator_Sum - Fatal编程技术网

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

Loops Haskell-每个矩阵中每个元素之间差异的总和,loops,haskell,matrix,iterator,sum,Loops,Haskell,Matrix,Iterator,Sum,我对Haskell(以及一般的函数编程)非常陌生,我正在尝试编写一个名为 “轮廓距离m1 m2”,以两个矩阵为参数,需要计算每个矩阵中每个元素之间的差值之和。。。我可能解释得不太清楚。让我来展示一下 矩阵的形式为:[[(Char,Int)] 其中每个矩阵可能如下所示: m1 = [[('A',1),('A',2)], [('B',3),('B',4)], [('C',5),('C',6)]] m2 = [[('A',7),('A',8)], [('B'

我对Haskell(以及一般的函数编程)非常陌生,我正在尝试编写一个名为 “轮廓距离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)]]
(注意:我在本例中按顺序写了数字,但它们可以是任何顺序的任何数字。但是,每个矩阵中每行的字符都将匹配,如示例所示。)

结果(在上述情况下)类似于(psuedo代码):

这在任何有for循环且非函数的语言中都很容易做到,但我不知道如何在Haskell中做到这一点。我觉得像
map
fold
sum
这样的函数在这里会对我有所帮助(诚然,我对
fold
的工作原理不是100%肯定)。我希望有一个简单的方法来做到这一点。。。请帮忙。

这里有一个建议:

solution m1 m2 = sum $ zipWith diffSnd flatM1 flatM2
  where
    diffSnd t1 t2 = snd t1 - snd t2
    flatM1 = concat m1
    flatM2 = concat m2
我写它是为了更容易理解构建块。 基本思想是使用
zipWith
在我们的两个配对列表上同时迭代。以下是其类型:

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
这意味着它接受一个类型为
a->b->c
的函数、一个
a
列表和一个
b
列表,并返回一个
c
列表。换句话说,
zipWith
以迭代为例,你只需要指定你想对迭代产生的每一项做什么,在你的例子中,这将是一对对对(一个来自第一个矩阵,另一个来自第二个矩阵)

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

还有最后一个问题。实际上,我们没有两个要传递给
zipWith
的配对列表!,但是有两个矩阵。我们需要在列表中“展平”它们,保持元素的顺序。这正是
concat
所做的,因此在
flatM1
flatM2
的定义中调用该函数


我建议您研究一下我提到的每个函数的实现,以便更好地理解迭代是如何通过递归来表示的。HTH

谢谢!工作得很好。@Schytheron:如果你需要差分作为矩阵,而不仅仅是求和,你也可以使用类似于
zipWith(zipWith diffSnd)
的东西,而不是用
concat
来压平结构。也可以使用
Data.Function
中的
on
使用
on
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]