Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 there some logical reason behind the absence of this method, or was it a mere oversight?

like image 578
missingfaktor Avatar asked Oct 11 '11 11:10

missingfaktor


2 Answers

  1. Because it's trivial to achieve the same by lifting the partial function

    partialFunc.lift(arg) getOrElse (totalFunc(arg))

  2. Because Scala, generally, tries to avoid overloading

  3. Because nobody thought to add it, and it's probably not been needed so far

  4. Because each and every method added to the standard library incurs an ever-growing cost in terms of downstream maintainence

like image 193
Kevin Wright Avatar answered Nov 11 '22 17:11

Kevin Wright


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.

like image 41
Daniel C. Sobral Avatar answered Nov 11 '22 18:11

Daniel C. Sobral