[英]Simplify pattern matching on type class instances with a certain member
I have this framework that defines a type class with most instances having a certain implicit value:我有这个框架,它定义了一个类型 class ,大多数实例都具有一定的隐含值:
import scala.reflect.runtime.universe.TypeTag
sealed trait Source
// many classes with implicit TypeTag
case class SourceA[T]()(implicit val ev: TypeTag[T]) extends Source
case class SourceB[T]()(implicit val ev: TypeTag[T]) extends Source
case class SourceC[T]()(implicit val ev: TypeTag[T]) extends Source
// a few classes without TypeTag
case class EmptySource() extends Source
In my app, I would like to access ev
in the above example using simple code.在我的应用程序中,我想使用简单的代码访问上述示例中的
ev
。 Here's what I've come up with:这是我想出的:
def retrieveTypeTagFromSource(source: Source): Option[TypeTag[_]] = source match {
case s: SourceA[_] => Some(s.ev)
case s: SourceB[_] => Some(s.ev)
case s: SourceC[_] => Some(s.ev)
// many more nearly identical lines
// then handling the remaining classes
case s: EmptySource => None
}
There are a lot of repetitions, not ideal.有很多重复,不理想。 I would like to eliminate them without merely transferring the repetitions to the framework side (eg adding a
HasTypeTag
trait to every applicable case class).我想消除它们,而不仅仅是将重复转移到框架端(例如,向每个适用的案例类添加
HasTypeTag
特征)。 I tried using the following line when pattern matching:我在模式匹配时尝试使用以下行:
case s: {val ev: TypeTag[Any]} => Some(s.ev)
but Scala warns a pattern match on a refinement type is unchecked
, so I don't know if that actually works.但是 Scala 警告
a pattern match on a refinement type is unchecked
,所以我不知道这是否真的有效。
Adding something like HasTypeTag
does not have to be repetitious, just have two different traits
and extend TaggedSource
or UntaggedSource
as appropriate.添加类似
HasTypeTag
的内容不必重复,只需具有两个不同的traits
并根据需要扩展TaggedSource
或UntaggedSource
。
import scala.reflect.runtime.universe.TypeTag
sealed trait Source
{
def ott: Option[TypeTag[_]]
}
abstract class TaggedSource[T]()(implicit val tt: TypeTag[T]) extends Source {
def ott = Some(tt)
}
trait UntaggedSource extends Source {
def ott = None
}
// many classes with implicit TypeTag
case class SourceA[T]()(implicit val ev: TypeTag[T]) extends TaggedSource[T]
case class SourceB[T]()(implicit val ev: TypeTag[T]) extends TaggedSource[T]
case class SourceC[T]()(implicit val ev: TypeTag[T]) extends TaggedSource[T]
// a few classes without TypeTag
case class EmptySource() extends UntaggedSource
def retrieveTypeTagFromSource(source: Source): Option[TypeTag[_]] =
source.ott
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.