我目前正在學習 Scala 課程,最近我學習了不同的回傳函式技術。
例如,給定這個函式和方法:
val simpleAddFunction = (x: Int, y: Int) => x y
def simpleAddMethod(x: Int, y: Int) = x y
我可以只回傳另一個函式:
val add7_v1 = (x: Int) => simpleAddFunction(x, 7)
val add7_v2 = simpleAddFunction(_: Int, 7)
val add7_v3 = (x: Int) => simpleAddMethod(x, 7)
val add7_v4 = simpleAddMethod(_: Int, 7)
所有的值 add7_x 完成同樣的事情,那么,柯里化的目的是什么?def simpleCurryMethod(x: Int)(y: Int) = x y如果上述所有功能都具有類似的功能,為什么我必須撰寫?
就是這樣!我是函式式編程的新手,除了通過減少重復使用引數來節省時間之外,我不知道 Currying 的許多用例。因此,如果有人可以向我解釋柯里化相對于前面的示例或一般柯里化的優勢,我將非常感激。
就這樣,祝你有美好的一天!
uj5u.com熱心網友回復:
在Scala 2中,柯里化 METHODS 只有四個務實的原因(據我所知,如果有人有另一個有效的用例,請告訴我)。
- (也可能是使用它的主要原因)來驅動型別推斷。
例如,當您想要接受一個函式或另一種型別的泛型值時,其泛型型別應該從一些普通資料中推斷出來。例如:
def applyTwice[A](a: A)(f: A => A): A = f(f(a))
applyTwice(10)(_ 1) // Here the compiler is able to infer that f is Int => Int
在上面的例子中,如果我沒有對函式進行柯里化,那么我需要做一些類似的事情:applyTwice(10, (x: Int) => x 1)呼叫函式。
這是多余的,看起來更糟(恕我直言)。
注意:在Scala 3 中型別推斷得到了改進,因此這個原因在那里不再有效。
- (并且可能是現在Scala 3 中的主要原因)呼叫者的 UX。
例如,如果你希望一個引數是一個函式或一個塊,它通常最好作為它自己(和最后一個)引數串列中的單個引數,這樣它在使用中看起來很不錯。例如:
def iterN(n: Int)(body: => Unit): Unit =
if (n > 0) {
body
iterN(n - 1)(body)
}
iterN(3) {
println("Hello")
// more code
println("World")
}
再說一次,如果我不使用前面的方法,用法應該是這樣的:
iterN(3, {
println("Hello")
// more code
println("World")
})
這看起來不太好:)
- (以我的經驗奇怪但有效)當您知道大多數用戶會部分呼叫它以回傳函式時。
因為val baz = foo(bar) _看起來比val baz = foo(bar, _)第一個更好,所以有時你不會像這樣使用下劃線:data.map(foo(bar))
注意:免責宣告,我個人認為如果是這種情況,最好立即回傳一個函式而不是柯里化。
編輯
感謝@jwvh 指出第四個用例。
- (在使用依賴于路徑的型別時很有用)當您需要參考之前的引數時。例如:
trait Foo {
type I
def bar(i: I): Baz
}
def run(foo: Foo)(i: foo.I): Baz =
foo.bar(i)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/312787.html
上一篇:如果定義了選項,如何將Option[Long]推送或附加到Seq[Long]?
下一篇:測驗Scala型別類的成員資格
