I wanted to try writing a type whose methods can be homogeneous and return values of the same type:
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()))
}
Unfortunately, the commented-out line calling tester
fails with the following error (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()))
^
Basically, I'm confused as to why X
and Y
don't unify to Foo
, which seems like a clear LUB for the two of them. Clearly the type member is complicating matters but its bounds appear to be respected.
At the higher level, I'm looking for a lightweight way to get the equivalent of F-bounded polymorphism without the overhead of pervasive type parameters. This mostly seems to work, but I need to add annotations that force X
and Y
to unify to Foo
.