fik*_*nik 17 methods scala function implicit-conversion
我想了解为什么eta-expansion(§6.26.5)不适用于重载方法.例如,如果我有以下两种方法:
def d1(a: Int, b: Int) {}
def r[A, B](delegate: (A, B) ? Unit) {}
Run Code Online (Sandbox Code Playgroud)
我可以做这个:
r(d1)
Run Code Online (Sandbox Code Playgroud)
但是,当重载r时它将不再起作用:
def r[A, B](delegate: (A, B) ? Unit) {}
def r[A, B, C](delegate: (A, B, C) ? Unit) {}
r(d1) // no longer compiles
Run Code Online (Sandbox Code Playgroud)
我必须显式地将方法转换为部分应用的函数:
r(d1 _)
Run Code Online (Sandbox Code Playgroud)
有没有办法通过显式转换完成以下操作?
def r[A, B](delegate: (A, B) ? Unit) {}
def r[A, B, C](delegate: (A, B, C) ? Unit) {}
def d1(a: Int, b: Int) {}
def d2(a: Int, b: Int, c: Int) {}
r(d1) // only compiles with r(d1 _)
r(d2) // only compiles with r(d2 _)
Run Code Online (Sandbox Code Playgroud)
There is somewhat similar question, but it is not fully explained.
som*_*ytt 15
隐含是正确的术语,规范中的部分是6.26.2,这必须是一个重复的问题(或者人们会想到;这是稳定的行为).
链接的问题也回答了预期的类型必须是一个函数.
我会指出,当超载时,适用性会被破坏,因为没有预期的类型(6.26.3,臭名昭着).未过载时,6.26.2适用(eta扩展),因为参数的类型决定了预期的类型.当重载时,arg是专门输入的,没有预期的类型,因此6.26.2不适用; 因此,任何超载变体均不d被视为适用.
从6.26.3重载决议
否则,让S 1,.... ..,S m是通过键入具有未定义的期望类型的每个参数而获得的类型的向量.
以下是在没有args的情况下命名方法时可用的"隐式转换"(所谓的),如r(d1).关于eta扩展的段落适用于此处.
6.26.2方法转换
以下四个隐式转换可以应用于未应用于某些参数列表的方法.
评价.类型=> T的无参数方法m总是通过计算m绑定的表达式转换为类型T.
隐式应用.如果该方法仅采用隐式参数,则遵循§7.2的规则传递隐式参数.
Eta扩张.否则,如果该方法不是构造函数,并且期望类型pt是函数类型(Ts)⇒T,则对表达式e执行eta-expansion(§6.26.5).
空应用程序.否则,如果e有方法类型()T,则它隐式应用于空参数列表,产生e()
更多绿色检查后的解释......
以下示例演示了在存在重载时更喜欢应用程序进行eta扩展.当eta-expansion不适用时,"空应用程序"是6.26.2中最后隐含的.换句话说,当过载(这是混乱和脸上的还不够邪恶),很自然地采取f如f()通过统一接入原则,但它是天然的或怪异采取f的f _,除非你很确定的函数类型是期待.
scala> object Bar {
| def r(f: () => Int) = 1
| def r(i: Int) = 2
| }
defined module Bar
scala> def f() = 4
f: ()Int
scala> Bar.r(f)
res4: Int = 2
scala> Bar.r(f _)
res5: Int = 1
Run Code Online (Sandbox Code Playgroud)
重载分辨率的候选者通过"形状"预先筛选.形状测试封装了从未使用过eta-expansion的直觉,因为args是在没有预期类型的情况下键入的.此示例显示即使是"表达式检查的唯一方法",也不使用eta-expansion.
scala> object Bar {
| def bar(f: () => Int) = 1
| def bar(is: Array[Int]) = 2
| }
defined object Bar
scala> def m() = 7
m: ()Int
scala> m _
res0: () => Int = <function0>
scala> Bar.bar(m)
<console>:10: error: overloaded method value bar with alternatives:
(is: Array[Int])Int <and>
(f: () => Int)Int
cannot be applied to (Int)
Bar.bar(m)
^
Run Code Online (Sandbox Code Playgroud)
任何阅读这篇文章的人都会对这两次转换的相关问题感到好奇.
| 归档时间: |
|
| 查看次数: |
1818 次 |
| 最近记录: |