2

I have a self-recursive type:

trait Problem[P <: Problem[P]] {
  type Solution
}

Now, I want to pattern match on P#Solution. Let's assume we're within the case class Foo[P <: Problem[P]]():

case ExampleCaseClass(s: P#Solution) if conditionApplies() =>
  // do sth

case ExampleCaseClass(s: P#Solution) =>
  // now sth else

Of course it fails due to type erasure. Is there any way to make that code compile in scala?

I've seen class/type tags but I'm not really sure if they can be use in such case.

slnowak
  • 1,839
  • 3
  • 23
  • 37

1 Answers1

2

You can indeed use type tags, but you need a concrete type to obtain the type tag from. You could add the solution type as type parameter:

case class Foo[P <: Problem[P], S <: P#Solution:TypeTag]() {
  def doSomething[T:TypeTag](c: ExampleCaseClass[T]) = c match {
    case ExampleCaseClass(s) if typeOf[T] =:= typeOf[S] => "x"
    case ExampleCaseClass(s) => "y"
  }
}

If you want a subtype match, use <:< instead of =:=.

devkat
  • 1,624
  • 14
  • 15
  • Seems to be a little bit noisy. What if I have to also pattern match on completely different class within the same block? – slnowak May 10 '16 at 08:12
  • 1
    If you need to match types that are eliminated by erasure, I don't think there is a more concise solution, but I would be very happy to hear about it. – devkat May 10 '16 at 09:07