scala – 如何删除重复的case语句以实现密封特征
发布时间:2020-12-16 18:39:18 所属栏目:安全 来源:网络整理
导读:我经常发现在为每个实现做同样的事情之前我需要提取密封特征的类型: sealed trait Traitcase class Foo() extends Traitcase class Bar() extends Trait// ... lots of other implementations// *must* take a `Trait`,not a `T : Trait`def thing(t: Trait
我经常发现在为每个实现做同样的事情之前我需要提取密封特征的类型:
sealed trait Trait case class Foo() extends Trait case class Bar() extends Trait // ... lots of other implementations // *must* take a `Trait`,not a `T <: Trait` def thing(t: Trait): ??? = t match { case f: Foo => // something with the instance and specific type case b: Bar => // something with the instance and specific type // ... same thing again for other implementations } 例如 // typically provided by somebody else... trait Thing[T] { def thingy: String } implicit def thing[T]: Thing[T] = new Thing[T] { def thingy = "stuff" } def thing(t: Trait): String = t match { case Foo() => implicitly[Thing[Foo]].thingy case Bar() => implicitly[Thing[Bar]].thingy // ... } 我想减少参与此操作的样板. 解决方法
更新:现在我们通过无形的方式使用类型派生.例如
https://github.com/fommil/shapeless-for-mortals
事实证明,你可以使用无形的’多态函数和联合产品来做到这一点: object thing extends Poly1 { implicit def action[T <: Trait: Thing] = at[T]( a => implicitly[Thing[T]].thingy ) // magic that makes it work at the sealed trait level def apply(t: Trait): String = Generic[Trait].to(t).map(thing).unify } 然后就可以使用了 println(thing(Foo(): Trait)) 我想通过抽象类更容易编写(让我们忘记现在将隐式参数传递给动作),例如 abstract class MatchSealed[In,Out] extends Poly1 { implicit def poly[T <: In] = at[T](action) def action[T <: In](t: T): Out import ops.coproduct.Mapper def apply[R <: HList](in: In)( implicit g: Generic.Aux[In,R],m: Mapper[this.type,R] ): Out = { val self: this.type = this g.to(in).map(self).unify } } 但是在最后一行丢失Mapper [self.type,g.Repr]失败了.我不知道哪个隐含缺失,但我怀疑它是self.type.我真的想捕获realisedSelf.type但我不知道该怎么做. 更新:事实证明,无法获取Mapper,因为它需要访问已实现的对象Unable to map on HList (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |