Reputation: 15
I want a generic base class which can be mixed in some traits.
Is it possible to have the mixins automatically adopt the generic type of the base class?
abstract class Base[T] {
def foo: T = ???
def bar(value: T): Boolean
}
trait MixinA {
self: Base[U] => // U should be automatically bound to T of Base[T]
def bar(value: U): Boolean = false
}
Upvotes: 0
Views: 229
Reputation: 32719
You can achieve something approaching this using an abstract type in Base
:
abstract class Base[T] {
type U <: T
def foo: U = ???
def bar(value: U): Boolean
}
trait MixinA {
self: Base[_] =>
final def bar(value: U): Boolean = false
}
REPL test:
scala> class Impl extends Base[Int] with MixinA
defined class Impl
scala> val i = new Impl
i: Impl = Impl@7ca5cc9e
scala> val x: Int = i.foo
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225)
at Base.foo(<console>:9)
... 33 elided
As you can see the compiler correctly determined that i.foo
is a sub-type of Int
(concretely, it is Int
) and thus can be assigned to x
(the exception here is just because you have left its body unimplemented).
Upvotes: 1
Reputation: 9168
In this case, you need U
to be a type parameter of your MixinA
.
trait MixinA[U] { self: Base[U] => ...
Type parameters are in a way like function parameters, if they are declared you need to pass them from somewhere (no magic).
Upvotes: 0