lazy val minkowskiHOF: (List[Double], List[Double], Int) => Double = (lstx, listy, p) => {
var add = lstx.zip(listy)
.map(pair => pair._1 - pair._2)
.foldLeft(0.0)((acumulator,element) => { Math.pow(Math.abs(element), p) + acumulator })
Math.pow(add, 1.0 / p)
}
答案 0 :(得分:2)
cgt :我有一个杯子。如何通过它钉钉?
每个人:出于什么目的?新杯应该如何不同?
cgt :它应该是完全相同的杯子。我想学习如何使用指甲。
Dmytro Mitin :将指甲粘在杯子的一侧。每当你使用杯子时都会忽略指甲。
cgt :谢谢Dmytro。这就是我想要的。
所以你想要做一个更高阶的功能。什么是高阶函数?它是一个函数,它接收函数作为传递参数和/或返回函数作为其结果。您可以通过多种方式将minkowski()
转换为更高阶的功能。
一个选项是使Math.pow()
部分成为传递参数。
val minkowskiHOF:(List[Double], List[Double], Int, (Double,Double)=>Double) => Double =
(lstx, listy, p, op) => {
val add = lstx.zip(listy)
.map(pair => Math.abs(pair._1 - pair._2))
.foldLeft(0.0)(_ + op(_, p))
op(add, 1.0 / p)
}
现在当您使用minkowskiHOF()
作为第4个参数调用Math.pow
时,您将获得Minkowski距离,但您也可以传递其他(Double,Double)=>Double
函数而不是{{1并得到一个不同的计算。所以现在Math.pow
对你的职能来说并不是一个非常好的名字。
或者,您可以返回一个函数。
minkowskiHOF()
这个val minkowskiHOF: (List[Double], Int) => List[Double] => Double =
(listy, p) => lstx => {
val add = lstx.zip(listy)
.map(pair => Math.abs(pair._1 - pair._2))
.foldLeft(0.0)(_ + Math.pow(_, p))
Math.pow(add, 1.0 / p)
}
函数完成了计算Minkowski距离的大部分工作,但它返回一个函数,只需一个minkowskiHOF()
即可完成计算。因此,List[Double]
可能不是一个完全准确的名称。
结论:高阶函数可以是一个非常方便的工具,但是,就像锤子和钉子一样,它并不总是适合每一个工作。