trait Entity:
type Key
object Entity:
type Aux[K] = Entity { type Key = K }
// match type
type EntityKey[T <: Entity] = T match
case Entity.Aux[k] => k // k being lower-case is significant
type Dictionary[T <: Entity] = Map[EntityKey[T], T]
I had to introduce Aux
-type because match types seem not to work with refined types
type EntityKey[T <: Entity] = T match
case Entity { type Key = k } => k // Not found: type k
Beware that on value level match types can work not so well as type projections: Scala 3: typed tuple zipping
- Besides match types, also type classes can be an alternative to general type projections
trait Entity:
type Key
// type class
trait EntityKey[T <: Entity]:
type Out
object EntityKey:
type Aux[T <: Entity, Out0] = EntityKey[T] { type Out = Out0 }
given [K]: EntityKey.Aux[Entity { type Key = K }, K] = null
// replacing the type with a trait
trait Dictionary[T <: Entity](using val entityKey: EntityKey[T]):
type Dict = Map[entityKey.Out, T]
What does Dotty offer to replace type projections?
https://users.scala-lang.org/t/converting-code-using-simple-type-projections-to-dotty/6516
Dotty cannot infer result type of generic Scala function taking type parameter trait with abstract type