簡體   English   中英

重載功能導致“擴展函數缺少參數類型”錯誤

[英]Overloaded function causes “missing parameter type for expanded function” error

我有以下內容:

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工作正常, 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

為什么FooList.foo不起作用?

有沒有辦法讓兩個FooList調用都工作?

似乎類型推斷僅在選擇適當的重載方法后才確定_ + _的類型,因此在靜態調度之前需要它明確地要求它; 但有解決方法:

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

如果您不想更改客戶端的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)
                                            ^

因此,調度在此處轉移到運行時,但實際接口保持不變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM