这些天我一直在学习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)
}
}
现在,如果我按如下方式调用它,这可以正常工作:
filter(List(1,2,3,4,5,6), ( (n:Int) => n % 2 == 0))
但是如果删除了类型标记,则看起来Scala无法推断出T的类型是Int。
filter(List(1,2,3,4,5,6), ( n => n % 2 == 0))
因此,我被迫在此调用中提供显式类型信息。
有人知道为什么Scala无法在此调用中推断出T的类型。该列表显然是Ints列表,我不明白为什么它不能推断出n的类型也是Int。
答案 0 :(得分:8)
Scala的类型推断适用于每个参数 list ,而不是每个参数,因此它在到达第二个谓词时尚未解析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)
}
现在以下内容可以正常使用:
scala> filter(List(1, 2, 3, 4, 5, 6))((n => n % 2 == 0))
res0: List[Int] = List(2, 4, 6)
有关其他讨论,请参阅我的回答here。
答案 1 :(得分:1)
您需要将谓词放在另一组参数中以推断工作:
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)
}
}
filter(List(1,2,3,4,5,6))(_ % 2 == 0)
不幸的是,这是scala的限制。