采用函数参数的重载泛型方法中的“缺少参数类型”

时间:2011-06-23 01:39:14

标签: generics scala overloading type-inference

我在DSL中遇到问题,重载泛型方法导致编译器希望我添加显式参数类型:

def alpha[T](fun: Int => T): String = fun(33).toString

def beta [T](fun: Int => T): String = fun(66).toString
def beta [T](thunk:   => T): String = thunk.toString

alpha { _ + 11 }          // ok
beta { _ + 22 }           // "error: missing parameter type for expanded function"
beta { _: Int => _ + 22 } // ok... ouch.

我有机会摆脱最后一行的混乱吗?

修改

为了证明重载不是scalac本身的歧义问题,这里是一个没有类型参数的版本,它完全正常:

def beta(fun: Int => String): String = fun(66).reverse
def beta(thunk:   => String): String = thunk.reverse

beta(_.toString)  // ok
beta("gaga")      // ok

2 个答案:

答案 0 :(得分:4)

问题是Int => T也是一种类型。例如,假设您只定义了第二个beta

def beta[ T ]( thunk: => T ) : String = thunk.toString

现在你将一个函数Int => Int传递给它:

scala> beta((_: Int) + 1)
res0: String = <function1>

所以,假设一个函数适合=> T,并且你有一个Int => T,那么Scala应该知道你想要哪一个?它可以是String,例如:

scala> beta((_: String) + 11)
res1: String = <function1>

Scala如何假设它是Int?你所展示的示例过载的例子不是责备不要展示任何这样的东西,因为你摆脱了它们中的类型参数。

答案 1 :(得分:1)

正如您可能已经意识到的那样,问题出现是因为您的beta函数已经过载。 定义时:

beta { _ + 22 }

你期望它打电话给哪个测试版? Scala无法知道_只是Int只是因为你用22求和它。所以对于这个特例,你必须定义_是什么。