В случае List(1,2,3).collect{case x => x.toString}
компилятор может вывести тип ввода частичной функции на основе того, как был введен List
.
final override def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[List[A], B, That])
На основе параметров типа компилятор может сделать вывод, что вы передаете правильно типизированную частичную функцию. Вот почему List(1,2,3).collect{case x:String => x.toString}
не компилируется, как и List(1,2,3).collect{case x:Int => x.toString; case x: String => x.toString}
.
Поскольку List
является ковариантным, компилятор может сделать вывод, что частичная функция {case x => x.toString}
является частичной функцией для Int
. Вы заметите, что List(1,2,3).collect{case x => x.length}
не компилируется, потому что компилятор делает вывод, что вы работаете либо с Int
, либо с подклассом Int
.
Также имейте в виду, что {case x => x.toString}
— это просто синтаксический сахар. Если мы сделаем что-то вроде приведенного ниже, ваш пример будет работать так, как ожидалось.
val f = new PartialFunction[Int, String](){
override def isDefinedAt(x: Int): Boolean = true
override def apply(v1: Int): String = v1.toString
}
val foo = PartialFunction[Int, String] { case 1 => "foo" }
val bar = foo orElse f //This compiles fine.
List(1,2,3).collect{f} // This works as well.
Таким образом, единственный логичный ответ, с моей точки зрения, заключается в том, что синтаксический сахар, способный генерировать экземпляр PartialFunction
для {case x => x.toString}
, не имеет достаточно информации во время компиляции, чтобы иметь возможность адекватно ввести его как PartialFunction[Int, String]
в вашем случае orElse
.
person
nattyddubbs
schedule
13.07.2016
collect
ожидаетPartialFunction[A, B]
, аorElse
ожидает[A1 <: A, B1 >: B] PartialFunction[A1, B1]
, поэтому, хотя компилятор может вывести первое, вам как-то нужно помочь со вторым. - person Peter Neyens   schedule 13.07.2016