user451151
user451151

Reputation: 406

Matching Type Parameters on Traits

Let's say I have a trait like:

trait MyTrait[T, U <: SomeParentClass] {
  def get(data: T): Option[U]
}

and a concrete implementation like:

case class MyStringClass[U <: SomeParentClass](f: String => Option[U])
  extends MyTrait[String, U] {
  override def get(data: String) = f(data)
}

To simplify things, let's also say we have the following types for U <: SomeParentClass:

and some functions:

Then let's say I have:

val mySeq = Seq(
  MyStringClass(str2TypeA),
  MyStringClass(str2TypeB),
  MyStringClass(str2TypeC)
)

What I want to do is filter mySeq based on the return type U. Something like:

mySeq.collect { case a: Function1[_, Option[TypeA]] => a}

I'm running into type erasure issues as expected. I'm curious what approaches might work well here to achieve my goal of filtering based on the type U.

Upvotes: 0

Views: 38

Answers (1)

Joe K
Joe K

Reputation: 18434

You would usually use a TypeTag to handle cases where erasure gets in your way. They are essentially simple objects that contain all of the information available at compile-time, and they're easy to obtain either by requesting an implicit parameter, or just writing typeTag[T]. For example:

import scala.reflect.runtime.universe._

case class MyStringClass[U <: SomeParentClass](f: String => Option[U])(implicit val utt: TypeTag[U])
  extends MyTrait[String, U] {
  override def get(data: String) = f(data)
}

mySeq.collect {
  case a: MyStringClass[Option[TypeA]] if (a.utt == typeTag[Option[Type[A]]) => a
}

Upvotes: 2

Related Questions