问题描述
我围绕 Aux-pattern 进行了一些实验,并发现 Aux
与编译器的集成在某种程度上更好。考虑以下两种情况:
我。
import Granularity.{Full,Partial}
sealed trait Granularity
object Granularity {
case object Full extends Granularity
sealed trait Partial extends Granularity {
type GranularityKey
}
object Partial{
type Aux[GK] = Partial{ type GranularityKey = GK }
}
}
sealed trait TestBub{
type G <: Granularity
}
object TestBub{
type Aux[GG <: Granularity] = TestBub{ type G = GG }
case class T1(i: Int) extends TestBub{
type G = Full.type
}
case class T2[Gr](j: String) extends TestBub{
type G = Partial.Aux[Gr]
}
def full[G <: Full.type](t: TestBub.Aux[G]): String = t match {
case T1(i) => i.toString
}
}
这段代码编译得很好没有警告。
二。
import Granularity.{Full,Partial}
sealed trait Granularity
object Granularity {
case object Full extends Granularity
sealed trait Partial extends Granularity {
type GranularityKey
}
object Partial{
type Aux[GK] = Partial{ type GranularityKey = GK }
}
}
sealed trait TestBub[G <: Granularity]
object TestBub{
case class T1(i: Int) extends TestBub[Full.type]
case class T2[Gr](j: String) extends TestBub[Partial.Aux[Gr]]
def full[G <: Full.type](t: TestBub[G]): String = t match {
case T1(i) => i.toString
}
}
此代码编译时发出警告。
match may not be exhaustive.
It would fail on the following input: T2(_)
问题:考虑到这两种情况,Aux 模式是否提供了一种在所有 ADT 分支的子集上进行模式匹配的更好方法?
解决方法
这是 Scala 2 类型系统的另一个问题。 Scala 3 在没有警告的情况下编译了第二种情况(正如预期的那样)。