scala – 如何自动生成一个函数以将密封的case类族与隐式实例匹
发布时间:2020-12-16 18:34:50 所属栏目:安全 来源:网络整理
导读:我有一个密封的案例类家族,它指定了一些规则,这些规则是从外部源反序列化的.我还有一个类型类,有几个实例来执行实际逻辑,如下所示: import scala.util.Trysealed trait ReaderConfigcase class Substring(begin: Int,end: Int) extends ReaderConfigcase cl
我有一个密封的案例类家族,它指定了一些规则,这些规则是从外部源反序列化的.我还有一个类型类,有几个实例来执行实际逻辑,如下所示:
import scala.util.Try sealed trait ReaderConfig case class Substring(begin: Int,end: Int) extends ReaderConfig case class Regex(expr: String) extends ReaderConfig trait Read[M[_],RC <: ReaderConfig] { def apply(config: RC,raw: String): M[String] } object Read { implicit val TryReadSubstring: Read[Try,Substring] = (config: Substring,raw: String) => Try { raw.substring(config.begin,config.end) } implicit val TryReadRegex: Read[Try,Regex] = (config: Regex,raw: String) => Try { config.expr.r.findFirstIn(raw).get } trait Helper[RC <: ReaderConfig] { def as[M[_]](implicit read: Read[M,RC]): M[String] } def apply[RC <: ReaderConfig](config: RC)(raw: String) = new Helper[RC] { override def as[M[_]](implicit read: Read[M,RC]): M[String] = read.apply(config,raw) } } 现在,在将其与具体类型一起使用时,找到正确的隐式是没有问题的. @ val ok: Try[String] = Read(Substring(0,1))("abc").as[Try] ok: Try[String] = Success("a") @ val Fail: Try[String] = Read(Substring(1000,9001))("abc").as[Try] Fail: Try[String] = Failure( java.lang.StringIndexOutOfBoundsException: String index out of range: 9001 ) 当我有一个val具有上层特征作为类型时(例如当我如上所述反序列化它)时,它无法按预期编译: @ val config: ReaderConfig = Substring(0,1) config: ReaderConfig = Substring(0,1) @ val fail2: Try[String] = Read(config)("abc").as[Try] cmd8.sc:1: could not find implicit value for parameter read: $sess.cmd2.Read[scala.util.Try,$sess.cmd1.ReaderConfig] val fail2: Try[String] = Read(config)("abc").as[Try] ^ Compilation Failed 我想出的唯一解决方案是编写一个函数,将实际类型与正确的实例相匹配,例如: val tryRead: ReaderConfig => String => Try[String] = {rc => raw => rc match { case s: Substring => Read[Substring](s)(raw).as[Try] case r: Regex => Read[Regex](r)(raw).as[Try] }} 然后它愉快地编译,我可以在那种情况下使用它. @ tryRead(config)("abc") res9: Try[String] = Success("a") 这个特性是密封的,所以编译器应该警告我有关丢失的情况,但很明显,只要我有更多这样的实例,它就会变得非常麻烦. 有什么方法可以自动生成此功能吗? 解决方法
我认为一个更常见的模式是为超类型(ReaderConfig)创建一个类型类实例,而不是为每个子类型创建一个实例.然后使用智能构造函数创建ReaderConfigs.例如,Cats为Option提供了一些构造函数:42.some返回Option [Int]而不是Some [Int].
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |