简体   繁体   中英

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
}

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).

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM