Pascal Will
Pascal Will

Reputation: 15

Automatically inferred generic type in trait

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

Answers (2)

Régis Jean-Gilles
Régis Jean-Gilles

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

cchantep
cchantep

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

Related Questions