Search code examples
scalamethodspattern-matchingargumentscase-class

Declaring a method to accept an unknown case class as argument to use it in pattern matching in Scala


Imagine a class A that is abstract and has a set of case classes. We don't know how many set classes are or even the name those case classes have.

abstract class A(field: String)
//Example of a case class that extends A
case class B(f: String) extends A(f)

Now I have this:

a match {
    case B(f) => println("f")
}

And I want to pass the case class type by an argument into a method. The reason I want this is because I will configure a set of rules in a file. And I want to load those rules and use pattern matching with some info those rules provide. I want to do something like this:

def printer (a: A, B: A) = {
   a match{
       case B(f) => println("f")
   }
}

Is this possible?

If it isn't that easy can I use an abstract class in pattern matching? It would be perfect if I could simply use the abstract class since it has the main structure of all case classes.

EDIT:

Forgot to mention that case classes can have different arguments so it would be good to use something based on class A (since I can do my pattern matching with the field only)


Solution

  • Not like you tried it. But if you use a Manifest as context bound, you can make it work:

    scala> trait Foo
    defined trait Foo
    
    scala> case class Bar(baz: String) extends Foo
    defined class Bar
    
    scala> def boo[A <: Foo : Manifest](foo: Foo) =
         |   if (foo.getClass isAssignableFrom manifest[A].erasure) "foo" else "boo"
    boo: [A <: Foo](foo: Foo)(implicit evidence$1: Manifest[A])java.lang.String
    
    scala> boo[Foo](Bar(""))
    res0: java.lang.String = boo
    
    scala> boo[Bar](Bar(""))
    res1: java.lang.String = foo