简体   繁体   English

Scala 中的 eta 扩展是什么?

[英]What is the eta expansion in Scala?

I am new to Scala.我是 Scala 的新手。 I just heard the term "eta expansion" and roughly know that it means to expand a method to a function object.刚听过“eta扩展”这个词,大致知道是将方法扩展为函数对象的意思。 But I find few resources in SO that systematically introduce it.但是我在 SO 中发现很少有资源可以系统地介绍它。

I am curious about how eta expansion works in Scala.我很好奇 eta 扩展在 Scala 中是如何工作的。 What are the scenarios that eta expansion are needed?需要eta扩展的场景有哪些? And how eta expansion is implemented in Scala?以及如何在 Scala 中实现eta 扩展

I roughly know that in cases like this:我大致知道在这种情况下:

def someMethod(x: Int): Int = x * x

someMethod _ will roughly be translated to a new function object like this: someMethod _将大致转换为一个新的函数对象,如下所示:

new Function1[Int, Int] {
  def apply(x: Int): Int = x * x
}

Is it all that Scala does?这就是 Scala 所做的一切吗?

The definition, and some examples, are given in http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#method-values . http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#method-values中给出了定义和一些示例。

someMethod _ will roughly be translated to a new function object like this: someMethod _将大致转换为一个新的函数对象,如下所示:

Not quite: it's actually不完全是:实际上是

new Function1[Int, Int] {
  def apply(x: Int): Int = someMethod(x)
}

The difference matters eg if someMethod is overridden somewhere.差异很重要,例如,如果someMethod在某处被覆盖。

Is it all that Scala does?这就是 Scala 所做的一切吗?

You also need to take into account what happens if the method takes multiple parameter lists (you get a function which returns a function) or by-name parameters.您还需要考虑如果该方法采用多个参数列表(您得到一个返回函数的函数)或按名称参数会发生什么。

What are the scenarios that eta expansion are needed?需要eta扩展的场景有哪些?

  1. When you specifically ask for it (eg someMethod _ ).当您特别要求时(例如someMethod _ )。

  2. When you use a method (with parameters) where a value of a function type (or a SAM type in Scala 2.12) is expected.当您使用需要函数类型(或 Scala 2.12 中的 SAM 类型)值的方法(带参数)时。 Eg例如

    def foo(f: Int => Int) = ??? foo(someMethod)
  3. That's it.就是这样。

Note that using eta-expansion and an anonymous function with placeholders ( someMethod(_) ) can behave differently due to type inference, implicits, etc.请注意,由于类型推断、隐式等原因,使用 eta-expansion 和带有占位符的匿名函数( someMethod(_) )可能会有不同的行为。

Eta expansion In high level, is a process of translating methods into functions. Eta 扩展在高层次上,是将方法转化为函数的过程。 Why?为什么? What?什么? Aren't them the same?他们不是一样的吗? Let's explain:让我们解释一下:

A method in scala is what we know as def someMethodName(SomePramList): SomeReturnType . scala 中的一个方法就是我们所知道的def someMethodName(SomePramList): SomeReturnType It starts with def .它以def开头。 It may have parameter list, or even maybe more then 1. For example:它可能有参数列表,甚至可能超过 1 个。例如:

def numAdder(num1: Int)(num2: Int): Int = 
    num1 + num2

A function , or lambda function looks something like: (SomeParams) => SomeReturnType .函数lambda函数类似于: (SomeParams) => SomeReturnType For example:例如:

val aFunction: Int => Int => Int = (num1: Int) => (num2: Int) => num1 + num2

Important to understand about functions is that this syntax is basically a syntactic sugar to FunctionN.apply method.理解函数的重要一点是,这种语法基本上是FunctionN.apply方法的语法糖。

What are the scenarios that eta expansion are needed?需要eta扩展的场景有哪些?

Some examples:一些例子:

Example1 - Applying a method inside map (or filter , flatMap etc)示例 1 - 在map (或filterflatMap等)中应用方法

Writing such code:编写这样的代码:

def addPlus1(x: Int): Int = x + 1
List(1,2,3).map(addPlus1)

The compiler needs to have a function inside the map .编译器需要在map有一个函数 So, it transforms the method given into a function: List(1,2,3).map(x => addPlus1(x)) .因此,它将给定的方法转换为一个函数: List(1,2,3).map(x => addPlus1(x)) This is Eta expansion .这是Eta expansion

Example2 - currying示例 2 - 柯里化

When defining curried method, for example:定义柯里化方法时,例如:

def numAdder(num1: Int)(num2: Int): Int = 
    num1 + num2

And them creating a function like:他们创建了一个函数,如:

val curriedFunction: Int => Int = numAdder(4)
//or
val curriedFunction2 = numAdder(4) _

We defined a function out of a method.我们从方法中定义了一个函数 This is Eta expansion .这是Eta expansion

Some more examples更多例子

Defined a method which accepts a function value:定义了一个接受函数值的方法:

def someMethod(f: () => Int): Int = f()
def method(): Int = 10

And then run:然后运行:

someMethod(method)

will transform the method method into a function.将方法method转换为函数。 This is Eta expansion这是Eta expansion

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM