在Scala 3中,如何替换掉的通用类型投影?

iyfjxgzm  于 2023-01-26  发布在  Scala
关注(0)|答案(1)|浏览(117)

这段代码在Scala 3中无法编译,因为抽象类型上的类型投影现在是无效的:

trait Entity:
  type Key

type Dictionary[T <: Entity] = Map[T#Key, T]

编译器抱怨T是抽象的,因此类型投影不再可用:

T is not a legal path
since it is not a concrete type

如何在Scala 3中定义上面的Dictionary类型?

3yhwsihp

3yhwsihp1#

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]

我不得不引入Aux-type,因为匹配类型似乎不适用于细化类型

type EntityKey[T <: Entity] = T match
  case Entity { type Key = k } => k // Not found: type k

请注意,在值级别上匹配类型可能不如类型投影工作得好。

  • 除了匹配类型之外,type classes也可以是一般类型投影的替代
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

相关问题