Kes*_*san 2 javascript functional-programming scala currying
我是 Scala 函数式编程的新手,我想知道如何在 Scala 中实现柯里化的概念。下面我给出了一个在 JavaScript 中柯里化的例子,我想知道相同代码的 Scala 等价物。
var add = function(x){
return function(y){
return x + y;
};
};
console.log(add(1)(2));
var increment = add(1);
var addTen = add(10);
increment(2); //3
addTen(2); //12
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激 :)
让我们首先用更现代的 ECMAScript 重写您的示例:
const add = x => y => x + y;
Run Code Online (Sandbox Code Playgroud)
Scala 等价物非常相似,它看起来几乎像这样,唯一的区别是val代替const(虽然我们实际上可以var在两种情况下使用,并使代码真正相同):
// almost correct, but doesn't compile
val add = x => y => x + y
Run Code Online (Sandbox Code Playgroud)
除了这不起作用,因为 Scala 不知道类型是什么,所以我们必须通过声明xand的类型来帮助一点y,所以 Scala 可以正确推断类型add 或声明类型add,所以 Scala可以正确推断函数的类型:
val add = (x: Int) => (y: Int) => x + y
// or
val add: Int => Int => Int = x => y => x + y
Run Code Online (Sandbox Code Playgroud)
如果我们想,Scala 还允许我们使用适当的粗箭头来编写它们:
val add = (x: Int) ? (y: Int) ? x + y
// or
val add: Int ? Int ? Int = x ? y ? x + y
Run Code Online (Sandbox Code Playgroud)
因此,如您所见,除了类型声明之外,代码实际上是相同的。
println(add(1)(2)) // 3
val increment = add(1)
val addTen = add(10)
increment(2) //=> 3
addTen(2) //=> 12
Run Code Online (Sandbox Code Playgroud)
然而,Scala 中还有另一种柯里化,它实际上是内置于语言中的。在 Scala 中,方法(不同于函数)可以有零个或多个参数列表,这与大多数其他语言(包括 ECMAScript)不同,后者总是只有一个(可能为空)参数列表。使用多个参数列表定义的方法称为“柯里化”方法:
// this is a *method*, not a *function*, and thus different from the OP's example!
def addMeth(x: Int)(y: Int) = x + y
Run Code Online (Sandbox Code Playgroud)
在 Scala 中,我们可以使用 ?-expansion 将方法转换为函数;这是通过在方法名称后放置下划线来编写的:
// this converts the method `addMeth` into an anonymous function
// and assigns it to the variable `addFunc`
val addFunc = addMeth _
Run Code Online (Sandbox Code Playgroud)
现在我们可以使用柯里化addFunc函数做与上面相同的事情:
println(addFunc(1)(2)) // 3
val increment = addFunc(1)
val addTen = addFunc(10)
increment(2) //=> 3
addTen(2) //=> 12
Run Code Online (Sandbox Code Playgroud)
但是我们也可以addMeth直接使用我们的方法:
println(addMeth(1)(2)) // 3
val increment = addMeth(1) _
val addTen = addMeth(10) _
increment(2) //=> 3
addTen(2) //=> 12
Run Code Online (Sandbox Code Playgroud)
所以,与 ECMAScript 不同,Scala 实际上有一个语言内置的柯里化概念,但是