[英]Overloaded function causes “missing parameter type for expanded function” error
I have the following: 我有以下内容:
class FooList[T] (data: List[T]) {
def foo (f: (T, T) => T, n: Int) = data.reduce(f)
def foo (f: (T, T) => T, s: String) = data.reduce(f)
}
class BarList[T] (data: List[T]) {
def bar(f: (T, T) => T, n: Int) = data.reduce(f)
}
BarList
works fine, FooList
fails: BarList
工作正常, FooList
失败:
scala> new FooList(List(1, 2, 3)).foo(_+_, 3)
<console>:9: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
new FooList(List(1, 2, 3)).foo(_+_, 3)
scala> new FooList(List(1, 2, 3)).foo(_+_, "3")
<console>:9: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
new FooList(List(1, 2, 3)).foo(_+_, "3")
^
scala> new BarList(List(1, 2, 3)).bar(_+_, 3)
res2: Int = 6
Why doesn't FooList.foo
work? 为什么FooList.foo
不起作用?
Is there any way to get the two FooList calls to both work? 有没有办法让两个FooList调用都工作?
It seems like type inference determines the type of _ + _
only after choosing appropriate overloaded method, so it requires it explicitly before static dispatch; 似乎类型推断仅在选择适当的重载方法后才确定_ + _
的类型,因此在静态调度之前需要它明确地要求它; however there is the workaround: 但有解决方法:
class FooList[T] (data: List[T]) {
def foo (n: Int)(f: (T, T) => T) = data.reduce(f)
def foo (s: String)(f: (T, T) => T) = data.reduce(f)
}
scala> new FooList(List(1, 2, 3)).foo(3)(_ + _)
res13: Int = 6
scala> new FooList(List(1, 2, 3)).foo("3")(_ + _)
res14: Int = 6
If you don't want to change the API for clients, you may merge two overloaded methods (second parameter becomes a union type then): 如果您不想更改客户端的API,则可以合并两个重载方法(第二个参数变为联合类型 ):
class FooList[T] (data: List[T]) {
def foo[A] (f: (T, T) => T, NorS: A)(implicit ev: (Int with String) <:< A) = NorS match {
case n: Int => data.reduce(f)
case s: String => data.reduce(f)
}
}
scala> new FooList(List(1, 2, 3)).foo(_ + _, "3")
res21: Int = 6
scala> new FooList(List(1, 2, 3)).foo(_ + _, 3)
res22: Int = 6
scala> new FooList(List(1, 2, 3)).foo(_ + _, 3.0)
<console>:15: error: Cannot prove that Int with String <:< Double.
new FooList(List(1, 2, 3)).foo(_ + _, 3.0)
^
So dispatching is moving to runtime here, but actual interface remains the same. 因此,调度在此处转移到运行时,但实际接口保持不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.