简体   繁体   English

简化具有特定成员的 class 类型实例的模式匹配

[英]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并根据需要扩展TaggedSourceUntaggedSource

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM