我可以找到一个文档,指定有关coercion of functions passed to higher-order function的Scala规则( ...方法decorator.layout会自动强制转换为Int => String 类型的值)。 / p>
如果我定义了以下内容。
object Foo {
def bar[T1, R](f: T1 => R): T1 => R = f
}
def fn1(s: String): Int = 1
然后在REPL中,我可以做到:
scala> Foo.bar({ s: String => 1 })
res: String => Int = <function1>
scala> Foo.bar(fn1)
res: String => Int = <function1>
一切都很好并且很清楚,但如果我更新Foo
:
object Foo {
def bar[T1, R](f: T1 => R): T1 => R = f
// NEW
def bar[T1, T2, R](f: Function2[T1, T2, R]): Tuple2[T1, T2] => R = { case (c1, c2) => f(c1, c2) }
}
然后在REPL中:
scala> Foo.bar({ s: String => 1 })
res: String => Int = <function1>
scala> Foo.bar(fn1)
<console>:12: error: missing arguments for method fn1;
follow this method with `_' if you want to treat it as a partially applied function
Foo.bar(fn1)
与bar(fn1)
的第一个版本一起使用的这个调用Foo
需要通过以下方式进行更新。
scala> Foo.bar(fn1 _)
res: String => Int = <function1>
这很好,但是我想确定Scala编译器遵循哪些规则,何时可以使用语法higherFn(fn)
以及何时不能使用语法{和语法higherFn(fn _)
是必需的)。
我猜高阶函数的多态性与...有关...
答案 0 :(得分:0)
简而言之,当编译器知道higherFn(fn1)
期望的类型时,可以使用fn
,如第一种情况中的T1 => R
。当发生重载时,编译器应首先选择适当的方法,因此当时的预期类型是未知的。
P.S。恕我直言,编译器在这里可能更聪明,但现在实现/描述似乎更复杂。