Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Pattern Matching with Sub-classes

Lift has the Box case class.

I wrote the following method to pattern match on a Box[A]:

scala> import net.liftweb.common._
import net.liftweb.common._

scala> def foo[A](box: Box[A]) = box match { 
     |   case Empty | Failure(_, _, _) => true
     |   case Full(_)                  => false
     | }
foo: [A](box: net.liftweb.common.Box[A])Boolean

I wrote this method to learn if ParamFailure, which is a sub-class of Failure, would pattern match on the Failure(_, _, _) case.

scala> val pf: Box[String] = ParamFailure("a", Empty, Empty, "blah")
pf: net.liftweb.common.Box[String] = ParamFailure(a, Empty, Empty, blah)

And, it did.

scala> foo(pf)
res9: Boolean = true

It's not clear to me why ParamFailure would match to Failure(_, _, _). Why is that?

like image 216
Kevin Meredith Avatar asked Apr 23 '26 07:04

Kevin Meredith


1 Answers

This is the whole point of inheritance. If S is a subclass of C, then you should be able to use S absolutely everywhere that you use C (this is called the Liskov Substitution Principle).

Pattern matching is included.

Now, if you specifically want to tell if you have an S as opposed to a C, you can check for it:

class C {}
class S extends C {}
val c: C = new S
c match {
  case s: S => println("Actually, I was an S")
  case _ => println("Guess I was some other kind of C")
}

But if you ask if it's a C, the answer is yes:

c match {
  case c2: C => println("Yes, of course I am a C!")
  case _ => println("This would be super-weird.")
}

Again, adding pattern matching changes nothing here; whether you know the type and then pull out the parameters by hand, or whether Scala helpfully gives you identifiers for them, it works the same way.

case class P(p: Boolean) {}
object T extends P(true) {}
val p: P = T
p match {
  case P(tf) => println(tf)
  case _ => println("You will never reach here.")
}
like image 134
Rex Kerr Avatar answered Apr 24 '26 21:04

Rex Kerr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!