我想尝试编写一个类型,其方法可以是同构的,并返回相同类型的值:
object SimpleTest { trait Foo extends Product with Serializable { type Self <: Foo def bar: Self } case class X() extends Foo { type Self = X def bar = this } case class Y() extends Foo { type Self = Y def bar = this } trait TC[A] implicit val tc: TC[Foo] = new TC[Foo] { } def tester[A: TC](x: Seq[A]) = "foo" // tester(Seq(X(),Y())) }
不幸的是,注释的线路调用测试仪失败并出现以下错误(Scala 2.10):
Error: Could not find implicit value for evidence parameter of type SimpleTest.TC[SimpleTest.Foo{type Self >: SimpleTest.Y with SimpleTest.X <: SimpleTest.Foo}] tester(Seq(X(),Y())) ^
基本上,我很困惑,为什么X和Y不统一到Foo,这对他们来说似乎是一个清晰的LUB.显然,该类型的成员是复杂的事情,但其界限似乎得到尊重.
在更高的层次上,我正在寻找一种轻量级的方式来获得相当于F边界多态性,而无需普遍类型参数的开销.这主要似乎有效,但是我需要添加强制X和Y统一到Foo的注释.
解决方法
我想这是你正在寻找的例子:
sealed trait Event { self => type E >: self.type <: Event def instance: E = self } case class UserJoined() extends Event { type E = UserJoined } case class UserLeft() extends Event { type E = UserLeft }
如果你想阅读更多,这个代码片段是a recent post,涵盖了相关的概念.
编辑:要完成答案,将是:
scala> trait Foo extends Product with Serializable with Event{} defined trait Foo scala> case class X() extends Foo { | type Self = X | def bar = this | } defined class X scala> case class Y() extends Foo { | type Self = Y | def bar = this | } defined class Y scala> List(X(),Y()) res9: List[Foo] = List(X(),Y()) scala> def tester[A: TC](x: Seq[A]) = "foo" tester: [A](x: Seq[A])(implicit evidence$1: TC[A])String scala> tester(Seq(X(),Y())) rES10: String = foo