【发布时间】:2021-08-11 14:16:58
【问题描述】:
只是玩弄一些 Scala 3 功能,我定义了一个 BooleanAlgebra[A],其中有 T <: A 和 B <: A。这些类型用于检查类型 A 是否已经归一化,我们不再需要检查它的边界。
Normailize 给我们T | F
当然需要 TypeTest,因为 T 和 F 类型在运行时会被删除。
该示例可以正常工作,但它抱怨无论何时我与T | F 匹配时匹配并不详尽,即使有来自T | F => T 和T | F => F 的TypeTag。请注意,我添加了 println 语句,以便您可以看到它的工作原理。
从 A => T | F、A => T 和 A => F 添加 TypeTag 也不起作用。
N 是必需的,因为 Scala 3 似乎不喜欢对可能改变的东西进行这种计算。在 Dotty 网站上的 Peano 示例中,如果将其切换为 Peano[A],它将停止正确匹配,但如果添加 type NAT = A 则可以正常工作。
任何关于如何使其正确匹配的想法将不胜感激。
这是代码示例:
trait BooleanAlgebra[A] {
final type N = A
type T <: N
type F <: N
val tru: T
val fls: F
final given TypeTest[T | F, T] =
x =>
println(" => T")
if x == tru then Some(tru.asInstanceOf[x.type & T])
else None
final given TypeTest[T | F, F] =
x =>
println(" => F")
if x == fls then Some(fls.asInstanceOf[x.type & F])
else None
def normalize(value: N): T | F
final def not(value: T | F): T | F =
value match
case _: T => fls
case _: F => tru
final def and(lhs: => T | F, rhs: => T | F): T | F =
lhs match
case _: T => rhs
case _: F => fls
final def or(lhs: => T | F, rhs: => T | F): T | F =
lhs match
case _: T => tru
case _: F => rhs
extension (lhs: => T | F) {
final def unary_! : T | F =
not(lhs)
final def |(rhs: => T | F): T | F =
or(lhs, rhs)
final def &(rhs: => T | F): T | F =
and(lhs, rhs)
}
}
object BooleanAlgebra {
def tru[A](using b: BooleanAlgebra[A]): b.T =
b.tru
def fls[A](using b: BooleanAlgebra[A]): b.F =
b.fls
def not[A](using b: BooleanAlgebra[A]): b.T | b.F => b.T | b.F =
value =>
b.not(value)
def norm[A](value: A)(using b: BooleanAlgebra[A]): b.T | b.F =
b.normalize(value)
}
示例实现
given BooleanAlgebra[Int] with {
type T = 1
type F = 0
val tru = 1
val fls = 0
def normalize(value: Int) =
if value > 0 then tru
else fls
}
【问题讨论】:
标签: scala union-types scala-3