当调用高阶的另一个函数时,Scala函数强制

时间:2015-04-12 12:43:21

标签: scala higher-order-functions

我可以找到一个文档,指定有关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 _)是必需的)。

我猜高阶函数的多态性与...有关...

1 个答案:

答案 0 :(得分:0)

简而言之,当编译器知道higherFn(fn1)期望的类型时,可以使用fn,如第一种情况中的T1 => R。当发生重载时,编译器应首先选择适当的方法,因此当时的预期类型是未知的。

P.S。恕我直言,编译器在这里可能更聪明,但现在实现/描述似乎更复杂。