I'm attempting to write an extractor(s) for use in matching against a multiple parameter case class. Simplified example:
case class X(p1: String, p2: Int)
I'd like each extractor objects to define a fixed value for p1, and p2 is defined on use. (A,B, etc cannot be a case class and subclass X, and I would also like to use X(,) as a case) Example with apply method:
object A {
def apply(p2: Int): X = X("A", p2)
}
object B {
def apply(p2: Int): X = X("B", p2)
}
...
For pattern matching, I would like them to match like this:
X("A", 2) match {
case A(2) => true // <- should match: p1="A" and p2=2
case A(_) => true // <- should match: p1="A" and p2=_
case X("A", _) => true // <- should match: p1="A" and p2=_
case A(1) => false // <- should not match
case B(2) => false // <- should not match: p1="B" and p2=2
}
I know I need to define unapply
method in A
, B
, etc., but I'm thoroughly confused what the signature and logic should be:
object A {
def unapply(x: ???): Option[???] = {
???
}
}
Assistance, please?
unapply
takes an Any and returns an Option
of whatever you want to extract. In your case this would be:
scala> case class X(p1: String, p2: Int)
defined class X
scala> object A {
| def unapply(target: Any): Option[Int] =
| PartialFunction.condOpt(target) {
| case X("A", p2) => p2
| }
| }
defined module A
scala> val A(x) = X("A", 1)
x: Int = 1
scala> val A(x) = X("B", 1)
scala.MatchError: X(B,1) (of class X)
...
But to be honest, the example you came up with could be rewritten without A
and B
:
X("A",2) match {
case X("A", 2) => true
case X("A", 1) => false
case X("A", _) => true
case X("B", 2) => false
}
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