Scala:函数值的eta扩展(不是方法)

编程入门 行业动态 更新时间:2024-10-10 15:20:56
本文介绍了Scala:函数值的eta扩展(不是方法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

在尝试使用scala的eta扩展后,我遇到了一个奇怪的功能. 让我们定义一个方法:

After experimenting with scala's eta expansion, I came across a weird feature. Let's define a method:

scala> def sum(a: Int, b: Int): Int = a + b sum: (a: Int, b: Int)Int

好的,到目前为止,一切都很好.现在,让我们使用eta扩展将其分配给val:

Ok, up until now, everything is fine. Now let's assign it to a val using eta expansion:

scala> val f = sum _ f: (Int, Int) => Int = $$Lambda$1051/694580932@55638165

现在,奇怪的事情来了.我可以再次将eta扩展应用于f,并且它正在工作(但是这会增加我的方法的麻烦):

Now, the strange thing is coming. I can apply eta expansion again to f, and it is working (however it adds currying to my method) :

scala> val g = f _ g: () => (Int, Int) => Int = $$Lambda$1055/1351568309@5602e540

这为什么起作用?我认为eta扩展仅对方法有效. 而且,我注意到这是不可能的:

Why is this working ? I thought that eta expansion was only valid for methods. Moreover, I noticed that this is not possible:

scala> ((a: Int, b: Int) => a + b: Int) _ <console>:12: error: _ must follow method; cannot follow (Int, Int) => Int ((a: Int, b: Int) => a + b: Int) _ ^

但是这与将eta扩展应用于f是不同的吗? 我有些困惑,这些eta扩展仍然为我隐藏了一些魔力. 非常感谢!

But is it not the same as applying eta expansion to f ? I am a bit confused and these eta expansions still hide some magic for me. Thanks a lot !

推荐答案

在REPL或对象/类的顶层编写val f = sum _时,Scala定义了一个访问器方法,以便您可以访问它.这是Scala如何消除这种情况的(通过val f: (Int, Int) => Int = _ + _上的scalac -Xprint:typer):

When you write val f = sum _ at the top level of the REPL or an object/class, Scala defines an accessor method so that you can access it. Here is how Scala desugars this (via scalac -Xprint:typer on val f: (Int, Int) => Int = _ + _):

private[this] val f: (Int, Int) => Int = ((x$1: Int, x$2: Int) => x$1.+(x$2)); <stable> <accessor> def f: (Int, Int) => Int = Foo.this.f;

因此,当您随后编写val g = f _时,它将对零参数访问器方法进行eta扩展,这将导致您看到的行为.要对此进行更多验证,请注意,如果将定义放入方法中,则会出现错误:

So, when you subsequently write val g = f _, it's doing eta-expansion on the zero-argument accessor method, which results in the behavior you see. For more verification of this, notice that, if you put the definitions in a method, you get an error:

def foo = { val f: (Int, Int) => Int = _ + _ val g = f _ // error: _ must follow method; cannot follow (Int, Int) => Int }

这是因为仅为字段(和顶级REPL定义,将其视为字段)生成访问器.

This is because accessors are only generated for fields (and top-level REPL definitions, which are treated like fields).

更多推荐

Scala:函数值的eta扩展(不是方法)

本文发布于:2023-11-25 23:24:56,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1631766.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   方法   Scala   eta

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!