In Scala, the PartialFunction[A, B]
class is derived from type Function[A, B]
(see Scala Reference, 12.3.3). However, this seems counterintuitive to me, since a Function
(which needs to be defined for all A
) has more stringent requirements than a PartialFunction
, which can be undefined at some places.
The problem I've came accross was that when I have a partial function, I cannot use a Function
to extend the partial function. Eg. I cannot do:
(pf orElse (_)=>"default")(x)
(Hope the syntax is at least remotely right)
Why is this subtyping done reversely? Are there any reasons that I've overlooked, like the fact that the Function
types are built-in?
BTW, it would be also nice if Function1 :> Function0
so I needn't have the dummy argument in the example above :-)
The difference between the two approaches can be emphasized by looking at two examples. Which of them is right?
One:
val zeroOne : PartialFunction[Float, Float] = { case 0 => 1 } val sinc = zeroOne orElse ((x) => sin(x)/x) // should this be a breach of promise?
Two:
def foo(f : (Int)=>Int) { print(f(1)) } val bar = new PartialFunction[Int, Int] { def apply(x : Int) = x/2 def isDefinedAt(x : Int) = x%2 == 0 } foo(bar) // should this be a breach of promise?
A partial function of type PartialFunction[A, B] is a unary function where the domain does not necessarily include all values of type A . The function isDefinedAt allows to test dynamically if a value is in the domain of the function.
=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .
In Scala, An anonymous function is also known as a function literal. A function which does not contain a name is known as an anonymous function. An anonymous function provides a lightweight function definition. It is useful when we want to create an inline function.
Because in Scala (as in any Turing complete language) there is no guarantee that a Function is total.
val f = {x : Int => 1 / x}
That function is not defined at 0. A PartialFunction is just a Function that promises to tell you where it's not defined. Still, Scala makes it easy enough to do what you want
def func2Partial[A,R](f : A => R) : PartialFunction[A,R] = {case x => f(x)} val pf : PartialFunction[Int, String] = {case 1 => "one"} val g = pf orElse func2Partial{_ : Int => "default"} scala> g(1) res0: String = one scala> g(2) res1: String = default
If you prefer, you can make func2Partial implicit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With