curriable 函数,returns scala 中的函数通过'=>',和(其次)通过 1 arg list 后跟另一个
curriable function that returns a function in scala via '=>', and (secondly), via 1 arg list followed by another
我开始学习一点 Scala,基本上
了解 return 函数和柯里化函数,但是
我已经看到了执行此操作的两种语法,我想更好
了解差异,也许还有一些背后的理论
怎么回事。
在第一种方法中(使用=>
)我可以通过指定
要绑定到变量 x
的参数。但是当我尝试这样做时
使用第二种方法,编译器告诉我需要指定 _
第二个参数的通配符。
我明白我需要做什么,但我不确定为什么我需要做
事情是这样的。有人可以告诉我 Scala 编译器是什么吗
在这里做什么?
第一种方法使用 =>
def add(x:Int) = (y:Int) => x + (-y)
add: (x: Int)Int => Int
scala> def adder = add(100) // x is bound to 100 in the returned closure
adder: Int => Int
scala> adder(1)
res42: Int = 99
第二种方法使用一个 arg 列表后跟另一个
scala> def add2(x:Int)(y:Int) : Int = x + y
add2: (x: Int)(y: Int)Int
scala> def adder2 = add2(100)
<console>:9: error: missing arguments for method add2;
follow this method with `_' if you want to treat it
as a partially applied function
def adder2 = add2(100)
^
scala> def adder2 = add2(100) _ // Okay, here is the '_'
adder2: Int => Int
scala> adder2(1) // Now i can call the curried function
res43: Int = 101
您看到的是 方法类型 和 函数类型 之间的区别。这是一个微妙的、有时令人困惑的区别。 This answer 包含对方法类型和函数类型之间差异的非常全面的解释。以下是与您的问题最相关的一些要点:
A Function Type is (roughly) a type of the form (T1, ..., Tn) => U
, which is a shorthand for the trait FunctionN
in the standard library.
A Method Type is a non-value type. That means there is no value - no object, no instance - with a method type... A method type is a def
declaration - everything about a def
except its body.
你不能直接分配一个方法做 val
:
def foo(x: Int) = x
val myFooVal = foo //does not compile
eta-expansion的过程可以将方法转化为函数,可以赋值给一个val
:
val myFooVal = foo _
Here 是一个更深入地探讨 eta 扩展的博客 post。
您的示例中有趣的是您将方法与函数混合在一起。这完全没问题,但这可能是您在这里感到困惑的一部分:
def add(x:Int) = (y:Int) => x + (-y)
这是方法 returns 一个函数,而这个:
def add2(x:Int)(y:Int) = x + y
是一个纯方法,与所有方法一样,可以使用 eta-expansion 转换为函数类型:
add2 _ //Int => (Int => Int)
add2(2) _ //Int => Int
在 REPL 中尝试一下,看看 Scala 如何以不同的方式处理这些类型可能会有所启发:
def add(x:Int) = (y:Int) => x + (-y)
//add: (x: Int)Int => Int
def add2(x:Int)(y:Int) = x + y
//add2: (x: Int)(y: Int)Int
注意这里 REPL 的打印输出有何不同。在第一个例子中,我们可以看到 add
是一个 returns 类型 Int => Int
的方法,它是一个函数。在第二个示例中,方法语法通过第二个参数保留。
我开始学习一点 Scala,基本上 了解 return 函数和柯里化函数,但是 我已经看到了执行此操作的两种语法,我想更好 了解差异,也许还有一些背后的理论 怎么回事。
在第一种方法中(使用=>
)我可以通过指定
要绑定到变量 x
的参数。但是当我尝试这样做时
使用第二种方法,编译器告诉我需要指定 _
第二个参数的通配符。
我明白我需要做什么,但我不确定为什么我需要做 事情是这样的。有人可以告诉我 Scala 编译器是什么吗 在这里做什么?
第一种方法使用 =>
def add(x:Int) = (y:Int) => x + (-y)
add: (x: Int)Int => Int
scala> def adder = add(100) // x is bound to 100 in the returned closure
adder: Int => Int
scala> adder(1)
res42: Int = 99
第二种方法使用一个 arg 列表后跟另一个
scala> def add2(x:Int)(y:Int) : Int = x + y
add2: (x: Int)(y: Int)Int
scala> def adder2 = add2(100)
<console>:9: error: missing arguments for method add2;
follow this method with `_' if you want to treat it
as a partially applied function
def adder2 = add2(100)
^
scala> def adder2 = add2(100) _ // Okay, here is the '_'
adder2: Int => Int
scala> adder2(1) // Now i can call the curried function
res43: Int = 101
您看到的是 方法类型 和 函数类型 之间的区别。这是一个微妙的、有时令人困惑的区别。 This answer 包含对方法类型和函数类型之间差异的非常全面的解释。以下是与您的问题最相关的一些要点:
A Function Type is (roughly) a type of the form
(T1, ..., Tn) => U
, which is a shorthand for the traitFunctionN
in the standard library.A Method Type is a non-value type. That means there is no value - no object, no instance - with a method type... A method type is a
def
declaration - everything about adef
except its body.
你不能直接分配一个方法做 val
:
def foo(x: Int) = x
val myFooVal = foo //does not compile
eta-expansion的过程可以将方法转化为函数,可以赋值给一个val
:
val myFooVal = foo _
Here 是一个更深入地探讨 eta 扩展的博客 post。
您的示例中有趣的是您将方法与函数混合在一起。这完全没问题,但这可能是您在这里感到困惑的一部分:
def add(x:Int) = (y:Int) => x + (-y)
这是方法 returns 一个函数,而这个:
def add2(x:Int)(y:Int) = x + y
是一个纯方法,与所有方法一样,可以使用 eta-expansion 转换为函数类型:
add2 _ //Int => (Int => Int)
add2(2) _ //Int => Int
在 REPL 中尝试一下,看看 Scala 如何以不同的方式处理这些类型可能会有所启发:
def add(x:Int) = (y:Int) => x + (-y)
//add: (x: Int)Int => Int
def add2(x:Int)(y:Int) = x + y
//add2: (x: Int)(y: Int)Int
注意这里 REPL 的打印输出有何不同。在第一个例子中,我们可以看到 add
是一个 returns 类型 Int => Int
的方法,它是一个函数。在第二个示例中,方法语法通过第二个参数保留。