在Scala中将以下代码转换为更高阶函数

时间:2017-10-05 19:57:10

标签: scala

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)
}

1 个答案:

答案 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]可能不是一个完全准确的名称。

结论:高阶函数可以是一个非常方便的工具,但是,就像锤子和钉子一样,它并不总是适合每一个工作。