Reputation: 406
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
:
TypeA
TypeB
TypeC
and some functions:
def str2TypeA(s: String): Option[TypeA] = ...
def str2TypeB(s: String): Option[TypeB] = ...
def str2TypeC(s: String): Option[TypeC] = ...
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
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