2012-09-30 92 views
10

假設我有2個參數,我需要部分應用功能,我需要把它定義爲:爲什麼在Scala中currying需要多個參數列表?

def f(a: Int)(b: Int) = { /* some code */ } 

,然後我可以部分地應用它作爲def fWithA = f(a) _

我的問題是:爲了爲了克服函數爲什麼Scala要求使用多個參數列表聲明參數?根據需要能夠咖喱任何功能將是優選的。

回答

15

'真正'的'currying'需要Scala中的多個參數列表:

  • 重載。與純粹的函數式語言不同,在Scala中,您可以重載方法。如果你部分應用了一個函數,那麼編譯器可能無法區分你的意思。該規範將超載分辨率限制爲第一個參數列表。

  • 錯誤消息。 「沒有足夠的方法調用參數」是一個非常有用(且易於理解)的錯誤消息。如果有人允許使用任何方法,那麼錯誤信息將是「必需的:但是」某些帶有許多箭頭的函數類型「

  • 性能:在JVM上運行使得調用方法非常高效,而函數通過一個接口調用)更慢

24

其實你可以部分應用你想要的任何方法。簡單地調用該方法,並留下了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> 
+0

這個提示如何咖喱任何類型的函數將是有用的。 – pramodbiligiri

相關問題