gpt4 book ai didi

斯卡拉 : eta expansion of function values (not methods)

转载 作者:行者123 更新时间:2023-12-04 18:19:35 24 4
gpt4 key购买 nike

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

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

好的,到目前为止,一切都很好。现在让我们使用 eta 扩展将其分配给 val:
scala> val f = sum _
f: (Int, Int) => Int = $$Lambda$1051/694580932@55638165

现在,奇怪的事情来了。我可以再次将 eta 扩展应用于 f,它正在工作(但是它在我的方法中添加了柯里化(Currying)):
scala> val g = f _
g: () => (Int, Int) => Int = $$Lambda$1055/1351568309@5602e540

为什么这行得通?我认为 eta 扩展只对方法有效。
此外,我注意到这是不可能的:
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 扩展仍然为我隐藏了一些魔力。
非常感谢 !

最佳答案

当你写 val f = sum _在 REPL 或对象/类的顶层,Scala 定义了一个访问器方法,以便您可以访问它。以下是 Scala 脱糖的方式(通过 scalac -Xprint:typer 上的 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 扩展,这会导致您看到的行为。要对此进行更多验证,请注意,如果将定义放入方法中,则会出现错误:
def foo = {
val f: (Int, Int) => Int = _ + _
val g = f _ // error: _ must follow method; cannot follow (Int, Int) => Int
}

这是因为只为字段(和顶级 REPL 定义,它们被视为字段)生成访问器。

关于斯卡拉 : eta expansion of function values (not methods),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52525520/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com