A Question Asker
A Question Asker

Reputation: 3311

Getting F-bounded polymorphism to work on a base trait with type parameters?

trait A[T, This[_] <: A[T, This]]
case class B[T]() extends A[T, B]

<console>:8: error: type arguments [T,B] do not conform to trait A's type parameter bounds [T,This[_] <: A[T,This]]
       case class B[T]() extends A[T, B]

This seems odd to me, because it seems like it should work? Guidance welcome...

Thank you

Upvotes: 0

Views: 57

Answers (1)

Ben Reich
Ben Reich

Reputation: 16324

It seems that you may have just misplaced the constraint on the second parameter:

trait A[T, This[_ <: A[T, This]]]
case class B[T]() extends A[T, B]

You could also try:

trait A[T, U <: A[T, U]]
case class B[T]() extends A[T, B[T]] 

If you want to mixin multiple such traits, you unfortunately can't use generics (you can't extend the same trait twice with different generic parameter). You can, however, use an abstract type member to express the F-Bound, and then mixin multiple such traits:

trait Step { self =>
    type Self <: Step { type Self <: self.Self }
    val name: String
    def next: Self
}

trait FooLike extends Step { 
    val fooMarker = "foo"
}
case class Foo(name: String) extends FooLike {
    type Self = Foo
    def next = Foo(name + "I")
}

trait BarLike extends Step {
    val barMarker = "bar"
}

case class FooBarLike(name: String) extends BarLike with FooLike {
    override type Self = FooBarLike
    override def next = this.copy(name + "J")
}

Upvotes: 2

Related Questions