【问题标题】:"Missing parameter type" in overloaded generic method taking a function argument采用函数参数的重载泛型方法中的“缺少参数类型”
【发布时间】:2011-06-23 01:39:13
【问题描述】:

我的 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

【问题讨论】:

    标签: generics scala overloading type-inference


    【解决方案1】:

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

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

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

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

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

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

    Scala 怎么会认为它是Int?您展示的用于演示重载的示例不应归咎于任何此类事情,因为您摆脱了其中的类型参数。

    【讨论】:

      【解决方案2】:

      您可能已经意识到,问题的出现是因为您的 beta 功能超载。 当你定义:

      beta { _ + 22 }
      

      您希望它调用哪个测试版? Scala 无法知道 _Int 只是因为您将其与 22 相加。因此对于这个特定示例,您必须定义 _ 是什么。

      【讨论】:

      • 可以,因为参数是Int => T。Scalac知道alpha的情况下为什么不知道beta的情况下?
      • 因为beta超载了,所以有两种选择,一种取Int =&gt; T,另一种取=&gt; T。这就是为什么如果不明确地告诉它,就不可能知道你指的是哪一个。 Alpha 之所以有效,正是因为只有一次选择。
      • 这不是真的。这是由于具有类型参数而导致的缺陷。如果方法不是通用的,我是否调用 thunk 或函数版本没有歧义。我已经编辑了问题以显示这一点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2023-03-31
      • 2021-10-18
      • 2017-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多