假設我有2個參數,我需要部分應用功能,我需要把它定義爲:爲什麼在Scala中currying需要多個參數列表?
def f(a: Int)(b: Int) = { /* some code */ }
,然後我可以部分地應用它作爲def fWithA = f(a) _
我的問題是:爲了爲了克服函數爲什麼Scala要求使用多個參數列表聲明參數?根據需要能夠咖喱任何功能將是優選的。
假設我有2個參數,我需要部分應用功能,我需要把它定義爲:爲什麼在Scala中currying需要多個參數列表?
def f(a: Int)(b: Int) = { /* some code */ }
,然後我可以部分地應用它作爲def fWithA = f(a) _
我的問題是:爲了爲了克服函數爲什麼Scala要求使用多個參數列表聲明參數?根據需要能夠咖喱任何功能將是優選的。
'真正'的'currying'需要Scala中的多個參數列表:
重載。與純粹的函數式語言不同,在Scala中,您可以重載方法。如果你部分應用了一個函數,那麼編譯器可能無法區分你的意思。該規範將超載分辨率限制爲第一個參數列表。
錯誤消息。 「沒有足夠的方法調用參數」是一個非常有用(且易於理解)的錯誤消息。如果有人允許使用任何方法,那麼錯誤信息將是「必需的:但是」某些帶有許多箭頭的函數類型「
性能:在JVM上運行使得調用方法非常高效,而函數通過一個接口調用)更慢
其實你可以部分應用你想要的任何方法。簡單地調用該方法,並留下了PARAMS:
scala> def foo(a: Int, b: Int) = a*b
foo: (a: Int, b: Int)Int
scala> val x = foo(1,_: Int)
x: Int => Int = <function1>
scala> def bar(x: Int, y: Int, z: Int) = x*y+z
bar: (x: Int, y: Int, z: Int)Int
scala> bar(2,_:Int,6)
res0: Int => Int = <function1>
唯一的區別是,你必須告訴編譯器丟失的參數的類型,否則它不能重載方法之間做出選擇。
另一種方式,如果你有一個真正的功能,而不是一個方法是調用的函數curried
:
scala> val f = {(x:Int, y:Int) => x*y}
f: (Int, Int) => Int = <function2>
scala> f.curried
res2: Int => (Int => Int) = <function1>
而且你還可以從與_
的方法創建一個功能:
scala> bar _
res6: (Int, Int, Int) => Int = <function3>
,然後調用curried
上:
scala> (bar _).curried
res5: Int => (Int => (Int => Int)) = <function1>
這個提示如何咖喱任何類型的函數將是有用的。 – pramodbiligiri