Nic*_*ler 9 functional-programming scala currying
我试图理解多个参数子句的这种语言特性以及为什么要使用它.例如,这两个功能之间的区别是什么?
class WTF {
def TwoParamClauses(x : Int)(y: Int) = x + y
def OneParamClause(x: Int, y : Int) = x + y
}
>> val underTest = new WTF
>> underTest.TwoParamClauses(1)(1) // result is '2'
>> underTest.OneParamClause(1,1) // result is '2'
Run Code Online (Sandbox Code Playgroud)
在第4.6点的Scala规范中有一些内容.看看这对你有意义.
注意:规范称这些'参数子句',但我认为有些人也可能称之为'参数列表'.
以下是多个参数列表的三种实际用法,
帮助类型推断.这在使用高阶方法时特别有用.下面,类型参数A的g2从第一参数推断x在第二个参数,所以函数的参数f可以被省略,
def g1[A](x: A, f: A => A) = f(x)
g1(2, x => x) // error: missing parameter type for argument x
def g2[A](x: A)(f: A => A) = f(x)
g2(2) {x => x} // type is inferred; also, a nice syntax
Run Code Online (Sandbox Code Playgroud)对于隐含参数.只有最后一个参数列表可以隐式标记,并且单个参数列表不能混合隐式和非隐式参数.以下定义g3需要两个参数列表,
// analogous to a context bound: g3[A : Ordering](x: A)
def g3[A](x: A)(implicit ev: Ordering[A]) {}
Run Code Online (Sandbox Code Playgroud)要根据以前的参数设置默认值,
def g4(x: Int, y: Int = 2*x) {} // error: not found value x
def g5(x: Int)(y: Int = 2*x) {} // OK
Run Code Online (Sandbox Code Playgroud)两个版本之间在类型推断方面存在差异.考虑
def f[A](a:A, aa:A) = null
f("x",1)
//Null = null
Run Code Online (Sandbox Code Playgroud)
这里,类型A被绑定Any,这是一个超类型String和Int.但:
def g[A](a:A)(aa:A) = null
g("x")(1)
error: type mismatch;
found : Int(1)
required: java.lang.String
g("x")(1)
^
Run Code Online (Sandbox Code Playgroud)
正如你看到的,类型检查只考虑第一个参数列表,以便A获取绑定到String,所以Int对于价值aa在第二个参数列表是一个类型的错误.