AaronDefazio
AaronDefazio

Reputation: 197

Why does this type alias not compile (Scala)

I'm trying to get code like the following to work:

abstract class Vec[Self <: Vec[Self,T], T] {
    this : Self =>
    def *(y : Self) : Self
}

abstract class LA[T] {
  type V <: Vec[V, T]
}

object typetest2 {
    def doesntcompile[L <: LA[Double]](x : L#V, y : L#V) : Unit = {
        val z = x * y
    }

    def compiles[V <: Vec[V,_]](x : V, y : V) : Unit = {
        val z = x * y
    }
}

But the compiler gives

[error]  found   : y.type (with underlying type L#V)
[error]  required: _9.V
[error]         val z = x * y
[error]                     ^

Is this a failure of the type checker or am I doing something wrong?

Upvotes: 4

Views: 161

Answers (1)

lmm
lmm

Reputation: 17431

While I'm not certain there's no workaround for this particular case, the compiler can't generically tell that two path-dependent types are equal even when they are.

You can generally solve such cases by adding an additional type parameter:

def compiles2[V1 <: Vec[V1, _], L <: LA[Double]{type V = V1}](x: L#V, y: L#V) = {
  val z = x * y
}

In some cases you might need to require an implicit =:= or Leibniz (Scalaz) to get the compiler to pass evidence that two types are equal down the chain.

Upvotes: 2

Related Questions