They don't seem to mix that well:
abstract class A
case class B (var a: Int)(var b: String) extends A
case class C extends A
The following will not work:
B(1)("1") match {
case B(a)(b) => print("B")
case C() => print("C")
}
The problem is that pattern matching and curried arguments do not seem to work. Is there a work-around for this?
Scala's pattern matching statement is most useful for matching on algebraic types expressed via case classes. Scala also allows the definition of patterns independently of case classes, using unapply methods in extractor objects.
Pattern matching is a way of checking the given sequence of tokens for the presence of the specific pattern. It is the most widely used feature in Scala. It is a technique for checking a value against a pattern. It is similar to the switch statement of Java and C.
Scala case classes are just regular classes which are immutable by default and decomposable through pattern matching. It uses equal method to compare instance structurally. It does not use new keyword to instantiate object. All the parameters listed in the case class are public and immutable by default.
A class can extend another class, whereas a case class can not extend another case class (because it would not be possible to correctly implement their equality).
If you look at the signature of the unapply function created for the class B, you will see that it is: unapply(x$0: Q): Option[Int]
. Thus, the unapply function works with the first range of parameter of the case classes.
It is confirmed by the scala specification (§5.3.2):
The formal parameters in the first parameter section of a case class are called elements; they are treated specially. First, the value of such a parameter can be extracted as a field of a constructor pattern.
It claims clearly tha only the first parameter section is available through the extractor.
Several workarounds:
case x@B(3) if x.b == "bazinga" => ...
What's wrong with this?
def m(a: A) = a match {
case b: B => print("B")
case c: C => print("C")
}
I'm only asking because you didn't ask for more functionality than this.
EDIT
This could help:
object Dog {
def apply(name: String)(size: Int) = new Dog(name)(size)
def unapply(dog: Dog) = Some(dog.name, dog.size)
}
class Dog(val name: String)(var size: Int)
Now you can create dogs either like this:
new Dog("Snoopy")(10)
or like this:
Dog("Snoopy")(10)
But when you pattern match on dogs the constructor pattern is not curried.
Dog("Snoopy")(10) match {
case Dog(a, b) => // do sth with a or b
}
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