参数函数的Scala类型推断问题

Edw*_*rzo 5 scala type-inference

这些天我一直在学习Scala,今天我遇到了一些我无法理解的问题.

假设我们有以下参数函数定义:

def filter[T](source: List[T], predicate: T=>Boolean): List[T] = {
    source match {
        case Nil => Nil
        case x::xs => if(predicate(x)) x::filter(xs, predicate)
                  else filter(xs, predicate)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我按如下方式调用它,这可以正常工作:

filter(List(1,2,3,4,5,6), ( (n:Int) => n % 2 == 0))
Run Code Online (Sandbox Code Playgroud)

但是如果删除类型标记,则看起来Scala无法推断出T的类型是Int.

filter(List(1,2,3,4,5,6), ( n => n % 2 == 0))
Run Code Online (Sandbox Code Playgroud)

所以,我被迫在这次调用中提供显式类型信息.

有没有人知道为什么Scala无法在此调用中推断出T的类型.该列表显然是Ints列表,我不明白为什么它不能推断出n的类型也是Int.

Tra*_*own 8

每个参数Scala的类型推断的作品列表,而不是每个参数,所以一直下不了决心T,以Int通过它得到你的第二个例子中的谓语时间.但是,您可以使用两个参数列表获得所需内容:

def filter[T](source: List[T])(predicate: T => Boolean): List[T] =
  source match {
    case Nil => Nil
    case x :: xs =>
      if (predicate(x))
        x :: filter(xs)(predicate)
      else
        filter(xs)(predicate)
  }
Run Code Online (Sandbox Code Playgroud)

现在以下内容将正常工作:

scala> filter(List(1, 2, 3, 4, 5, 6))((n => n % 2 == 0))
res0: List[Int] = List(2, 4, 6)
Run Code Online (Sandbox Code Playgroud)

见我的答案在这里一些额外的讨论.