Inference of type parameters on mixins

Viewed 52

Let's say I have some trait:

trait A[T] { def foo: T }

A class which extends it:

class B[T](t: T) extends A[T] { def foo = t }

And a subtrait of the parent trait:

trait C[T] extends A[T]

I want to mix C in with B.

val foo = new B("foo") with C[String]

This works fine, but I'd rather not need to specify the type parameter again, since B is already of type A[String]. However, I recognize Scala doesn't support the following:

val foo = new B("foo") with C

My question is where there's some other mechanism in the type system to support not having to specify the type parameters when C is mixed in. What I was thinking of was something as follows:

trait C {
  self: A[T] => ...
}

One would think this kind of thing would fix what C could be mixed into. However, it isn't valid Scala. Something like:

trait C {
  type T
  self: A[T] =>
}

does not work either.

2 Answers

How about this:

scala> trait C {
     |   self: A[_] => 
     | }
defined trait C

scala> val foo = new B("foo") with C
foo: B[String] with C = $anon$1@f2df380

scala> foo.foo
res16: String = foo

You can do this using an abstract type:

  trait A {
    type AT
    def foo: AT
  }

  class B[T](t: T) extends A {
    type AT = T 
    def foo = t
  }

  trait C extends A

  val foo = new B("foo") with C

The definition is a bit more verbose, but your requirement of not having to type T again is satisfied.

Related