Thunk vs Function重载

时间:2014-04-13 23:17:01

标签: scala

我想定义一个重载方法,一个接受一个function0,另一个接受一个function1,即:

def produces(f: Context => Any): Processor = ...

def produces(thunk: => Any): Processor = ...

这编译很好,因为第一个编译为使用Function1而第二个编译使用Function0,但是当我想调用时会出现问题,因此:

produces {
 ctx => "hello"
}

给我一​​个

  

缺少参数类型

只有一个参数接受输入,所以为什么不能推断。

有关我可以做些什么来解决这个问题的任何提示(除了重命名其中一种方法之外:))

2 个答案:

答案 0 :(得分:2)

这看起来很傻,但你可以(笨拙地)帮助编译器的搜索策略,要求隐式转换I-can-take-anything-by-name版本:

object Test {
  implicit def low_priority_conversion(t: Test.type) = LowPriority
  object LowPriority {
    def produces(x: => Any) : Boolean = false
  }
  def produces(f: String => Any): Boolean = true
}

无论您是否import Test._,您都会发现行为正确:

scala> Test.produces("fish")
res0: Boolean = false

scala> Test.produces(_.length)
res1: Boolean = true

scala> import Test._
import Test._

scala> produces("fish")
res2: Boolean = false

scala> produces(_.length)
res3: Boolean = true

答案 1 :(得分:0)

我认为这里真正的答案是“不要那样做”! ;-)你传递的参数实际上对你的两个函数都有效。您遇到错误而不是让编译器静默调用“错误”/意外函数的唯一原因是因为它无法推断[]的类型(这只是因为Scala的类型推导者不支持统一(还))。

基本上,您的问题是ctxAny的超类型。

如果你真的想要将两个函数命名为相同,另一种方法是让其中一个函数将thunk作为参数而不是名字Context => Any。 (但是你需要将你想要传递给thunk版本的任何参数发送到thunk版本而不是隐式评估它。)

例如:

Any