有幾個原因可能導致您偏好部分應用功能。最明顯也許很膚淺的一個是,你不必寫出如addOnePA
這樣的中間函數。
List(1, 2, 3, 4) map (_ + 3) // List(4, 5, 6, 7)
是更好比
def add3(x: Int): Int = x + 3
List(1, 2, 3, 4) map add3
即使是匿名函數的方法(即下劃線結束了向外擴展到編譯器)的感覺一點點笨重的比較。
List(1, 2, 3, 4) map (x => x + 3)
當你真正將函數作爲一流值傳遞時,表面上看,部分應用程序不那麼膚淺,派上用場了。
val fs = List[(Int, Int) => Int](_ + _, _ * _, _/_)
val on3 = fs map (f => f(_, 3)) // partial application
val allTogether = on3.foldLeft{identity[Int] _}{_ compose _}
allTogether(6) // (6/3) * 3 + 3 = 9
試想一下,如果我沒有告訴你什麼fs
功能者。使用命名函數替代部分應用程序的技巧變得更難以使用。對於柯里化來說,柯里裏函數經常可以讓你自然地表達產生其他函數的函數的變換(而不是更高階的函數,最終產生一個非函數值),否則這些函數可能會不那麼清晰。
例如,
def integrate(f: Double => Double, delta: Double = 0.01)(x: Double): Double = {
val domain = Range.Double(0.0, x, delta)
domain.foldLeft(0.0){case (acc, a) => delta * f(a) + acc
}
可以被認爲和你實際學會了微積分的整合,即作爲生產其他功能的功能的改造方式使用。
def square(x: Double): Double = x * x
// Ignoring issues of numerical stability for the moment...
// The underscore is really just a wart that Scala requires to bind it to a val
val cubic = integrate(square) _
val quartic = integrate(cubic) _
val quintic = integrate(quartic) _
// Not *utterly* horrible for a two line numerical integration function
cubic(1) // 0.32835000000000014
quartic(1) // 0.0800415
quintic(1) // 0.015449626499999999
柯里格還減輕了固定功能性的一些問題。
implicit class LiftedApply[A, B](fOpt: Option[A => B]){
def ap(xOpt: Option[A]): Option[B] = for {
f <- fOpt
x <- xOpt
} yield f(x)
}
def not(x: Boolean): Boolean = !x
def and(x: Boolean)(y: Boolean): Boolean = x && y
def and3(x: Boolean)(y: Boolean)(z: Boolean): Boolean = x && y && z
Some(not _) ap Some(false) // true
Some(and _) ap Some(true) ap Some(true) // true
Some(and3 _) ap Some(true) ap Some(true) ap Some(true) // true
通過具有令行禁止的功能,我們已經能夠「提升」功能對Option
工作,儘可能多的爭論,因爲我們所需要的。如果我們的邏輯功能尚未被使用,那麼我們將不得不分別執行A => B
到Option[A] => Option[B]
,(A, B) => C
到(Option[A], Option[B]) => Option[C]
,(A, B, C) => D
到(Option[A], Option[B], Option[C]) => Option[D]
等等我們關心的所有ar們。
當涉及到類型推斷時,Currying也有一些其他的好處,如果你有一個方法的參數implicit
和非implicit
,那麼它是必需的。
Finally, the answers to this question列出了一些你可能想要的咖喱。
重複其他幾個問題 –
柯里格訴v.s的有用性(在實際應用中)可能的重複。部分應用程序在斯卡拉](http://stackoverflow.com/questions/8063325/usefulness-as-in-practical-applications-of-currying-vs-partial-application-i) –
我不是問關於柯里與部分應用函數,我正在問卷曲/部分應用函數與重載函數 –