Lif*_*ang 17 scala eta-expansion
我是Scala的新手.我刚刚听到"eta扩展"一词,并且大致知道它意味着将方法扩展为函数对象.但我发现很少有资源可以系统地介绍它.
我很好奇eta扩展在Scala中是如何工作的.需要进行eta扩展的场景是什么?以及如何在Scala中实现eta扩展?
我大致知道在这种情况下:
def someMethod(x: Int): Int = x * x
Run Code Online (Sandbox Code Playgroud)
someMethod _ 将大致翻译成一个新的函数对象,如下所示:
new Function1[Int, Int] {
def apply(x: Int): Int = x * x
}
Run Code Online (Sandbox Code Playgroud)
是Scala的全部吗?
Aar*_*_ab 17
Eta 扩展在高层次上,是将方法转化为函数的过程。为什么?什么?他们不是一样的吗?让我们解释一下:
scala 中的方法就是我们所知道的def someMethodName(SomePramList): SomeReturnType. 它以 开头def。它可能有参数列表,甚至可能超过 1 个。例如:
def numAdder(num1: Int)(num2: Int): Int =
num1 + num2
Run Code Online (Sandbox Code Playgroud)
一个函数或lambda函数看起来是这样的:(SomeParams) => SomeReturnType。例如:
val aFunction: Int => Int => Int = (num1: Int) => (num2: Int) => num1 + num2
Run Code Online (Sandbox Code Playgroud)
理解函数的重要一点是,这种语法基本上是FunctionN.apply方法的语法糖。
需要eta扩展的场景有哪些?
一些例子:
例1 -申请的方法的内部map(或filter,flatMap等)
编写这样的代码:
def addPlus1(x: Int): Int = x + 1
List(1,2,3).map(addPlus1)
Run Code Online (Sandbox Code Playgroud)
编译器需要有一个函数里面的map。因此,它将给定的方法转换为函数:
List(1,2,3).map(x => addPlus1(x))。这是Eta expansion。
示例 2 - 柯里化
定义柯里化方法时,例如:
def numAdder(num1: Int)(num2: Int): Int =
num1 + num2
Run Code Online (Sandbox Code Playgroud)
他们创建了一个函数,如:
val curriedFunction: Int => Int = numAdder(4)
//or
val curriedFunction2 = numAdder(4) _
Run Code Online (Sandbox Code Playgroud)
我们从方法中定义了一个函数。这是Eta expansion。
更多例子
定义了一个接受函数值的方法:
def someMethod(f: () => Int): Int = f()
def method(): Int = 10
Run Code Online (Sandbox Code Playgroud)
然后运行:
someMethod(method)
Run Code Online (Sandbox Code Playgroud)
将方法method转换为函数。这是Eta expansion
Ale*_*nov 16
定义和一些示例在http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#method-values中给出.
someMethod _将大致翻译成一个新的函数对象,如下所示:
不完全是:实际上
new Function1[Int, Int] {
def apply(x: Int): Int = someMethod(x)
}
Run Code Online (Sandbox Code Playgroud)
差异很重要,例如,如果someMethod在某处被覆盖.
是Scala的全部吗?
如果方法采用多个参数列表(您获得一个返回函数的函数)或按名称参数,您还需要考虑会发生什么.
需要进行eta扩展的场景是什么?
当你特别要求它时(例如someMethod _).
当您使用一个方法(带参数)时,需要一个函数类型的值(或Scala 2.12中的SAM类型).例如
def foo(f: Int => Int) = ???
foo(someMethod)
Run Code Online (Sandbox Code Playgroud)而已.
请注意,使用eta-expansion和带有占位符(someMethod(_))的匿名函数可能会因类型推断,隐含等而表现不同.
| 归档时间: |
|
| 查看次数: |
3965 次 |
| 最近记录: |