In many Scala tutorials & marketing materials, I found many people abusing terminology by mingling "type alias" and "dependent type", while in reality they are not the same thing.
E.g. in the following example, TakeAlias is a dependent type, not a type alias. As a result, it will cause compilation to fail:
object TrueTypeAlias {
trait Unaliased[+T] {
def take1: List[Seq[(T, T)]]
def take2: List[Seq[(T, T)]]
def take3: List[Seq[(T, T)]]
}
trait Aliased[+T] {
type TakeAlias = List[Seq[(T, T)]]
def take1: TakeAlias
def take2: TakeAlias
def take3: TakeAlias
}
}
/*
TrueTypeAlias.scala:16:10: covariant type T occurs in invariant position in type = List[Seq[(T, T)]] of type TakeAlias
one error found
*/
The problem is: what does it take to implement true type alias? Is there a compiler mechanism/extension I can use to make it work?
type TakeAlias = List[Seq[(T, T)]]is a type alias in the sense thatTakeAliascan be used instead ofList[Seq[(T, T)]].At the same time
type TakeAlias = ...is a type member of the trait. Sox.TakeAlias(forx: Aliased[T]) is a path-dependent type. Although this path dependency is now trivial:x.TakeAliasare the same for differentx: Aliased[T]with the sameT, namely allx.TakeAliasareList[Seq[(T, T)]]. And sincetype TakeAlias = ...is a type member, all variance-position restrictions are applied.I'd fix this code making type alias generic
or extracting type alias outside (for example to companion)
A quote from the spec:
https://scala-lang.org/files/archive/spec/2.13/04-basic-declarations-and-definitions.html#variance-annotations
Also when you're sure that illegal usage can't lead to issues in your use case you can use
scala.annotation.unchecked.uncheckedVarianceor