Why isn't there an orElse method on PartialFunction that accepts a total function?
Why is there no method with following signature on class PartialFunction[A, B]
?
def orElse[A1 <: A, B1 >: B](that: A1 => B1): A1 => B1
Is开发者_C百科 there some logical reason behind the absence of this method, or was it a mere oversight?
Because it's trivial to achieve the same by lifting the partial function
partialFunc.lift(arg) getOrElse (totalFunc(arg))
Because Scala, generally, tries to avoid overloading
Because nobody thought to add it, and it's probably not been needed so far
Because each and every method added to the standard library incurs an ever-growing cost in terms of downstream maintainence
Consider,
scala> object O {
| def f(g: Int => Int) = g(1)
| def f(g: PartialFunction[Int, Int]) = g(2).toString
| }
defined module O
scala> O f { _ * 1 }
res3: Int = 1
So, how do you chain partial functions now? Or, in other words, if the overload you describe was in the library, and I wrote this:
type PF = PartialFunction[Any, Int]
val pf1: PF = { case n: Int => n }
val pf2: PF = pf1 orElse { case x: String => x.length }
val pf3: PF = pf2 orElse { case d: Double => d.toInt }
I'd get an error message on pf2
because of the ambiguity of the type. If, instead, I write:
val pf2 = pf1 orElse ((_: Any) match { case x: String => x.length })
val pf3 = pf2 orElse ((_: Any) match { case d: Double => d.toInt })
Then I get an error on pf3
, because pf2
will be a Function1
.
It appears there isn't any good reason for the absence of these functions in the standard library, other than oversight or maybe nobody needs these as often as to have them in standard library.
I have defined an implicit conversion from A => B
to PartialFunction[A, B]
which seems to take care of this and other similar cases, and doesn't lead to adverse effects.
scala> implicit def fToPf[A, B](f: A => B) = new PartialFunction[A, B] {
| def isDefinedAt(a: A) = true
| def apply(a: A) = f(a)
| }
fToPf: [A, B](f: A => B)java.lang.Object with PartialFunction[A,B]
精彩评论