给定不透明类型X
、Y
,是否可能有一个返回类型Table[X, Y]
,它解析为X
、Y
或第三个类型Z
之一?
下面的代码(显然)无法编译:
opaque type ConstrainedInt = Int
opaque type PositiveInt <: ConstrainedInt = Int
opaque type NegativeInt <: ConstrainedInt = Int
object PositiveInt:
def apply(n: Int): PositiveInt =
require(n > 0)
n
object NegativeInt:
def apply(n: Int): NegativeInt =
require(n < 0)
n
type AddType[PositiveInt, PositiveInt] = PositiveInt
type AddType[NegativeInt, NegativeInt] = NegativeInt
extension[X <: ConstrainedInt](x: X)
def +[Y <: ConstrainedInt](y: Y): AddType[X, Y] = x + y
类型类版本也不能编译
trait AddType[X <: ConstrainedInt, Y <: ConstrainedInt]:
type Result <: ConstrainedInt
given AddType[PositiveInt, PositiveInt] = new AddType { type Type = PositiveInt }
given AddType[NegativeInt, NegativeInt] = new AddType { type Type = NegativeInt }
extension[X <: ConstrainedInt](x: X)
def +[Y <: ConstrainedInt](y: Y)(using t: AddType[X, Y]): t.Result = x + y
生产
[E007] Type Mismatch Error: cmd2.sc:22:77 -----------------------------------
22 | def +[Y <: ConstrainedInt](m: Y)(using t: AddType[X, Y]): t.Result = n + m
| ^^^^^
| Found: Int
| Required: t.Result
更新
试着遵循https://stackoverflow.com/a/76046222的建议。constrained.scala
object constrained:
opaque type PositiveInt = Int
opaque type NegativeInt = Int
object PositiveInt:
def apply(n: Int): PositiveInt =
require(n > 0)
n
object NegativeInt:
def apply(n: Int): NegativeInt =
require(n < 0)
n
extension[X <: PositiveInt | NegativeInt](x: X)
def +[Y <: PositiveInt | NegativeInt](y: Y): TypeTables.AddType[X, Y] = x + y
TypeTables.scala
object TypeTables:
import constrained.*
type AddType[X <: PositiveInt | NegativeInt, Y <: PositiveInt | NegativeInt] = X match
case PositiveInt => Y match
case PositiveInt => PositiveInt
case NegativeInt => Int
case NegativeInt => Y match
case NegativeInt => NegativeInt
case PositiveInt => Int
scalac constrained.scala TypeTables.scala
scala -classpath .
scala> import constrained.*
scala> import TypeTables.*
scala> PositiveInt(3) + NegativeInt(-4)
val res0:
constrained.NegativeInt match {
case constrained.PositiveInt => constrained.PositiveInt
case constrained.NegativeInt => Int
} = -1
scala> NegativeInt(-4) + PositiveInt(3)
val res1: TypeTables.AddType[constrained.NegativeInt, constrained.PositiveInt] = -1
scala> NegativeInt(-3) + NegativeInt(-4)
|
val res2: TypeTables.AddType[constrained.NegativeInt, constrained.NegativeInt] = -7
scala> val a: Int = PositiveInt(3) + NegativeInt(-4)
-- [E007] Type Mismatch Error: ---------------------------------------------------------------------
1 |val a: Int = PositiveInt(3) + NegativeInt(-4)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Found: constrained.NegativeInt match {
| case constrained.PositiveInt => constrained.PositiveInt
| case constrained.NegativeInt => Int
| }
| Required: Int
|
| longer explanation available when compiling with `-explain`
1 error found
scala> val a: NegativeInt = NegativeInt(-4) + NegativeInt(-3)
-- [E007] Type Mismatch Error: ---------------------------------------------------------------------
1 |val a: NegativeInt = NegativeInt(-4) + NegativeInt(-3)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Found: TypeTables.AddType[constrained.NegativeInt, constrained.NegativeInt]
| Required: constrained.NegativeInt
|
| Note: a match type could not be fully reduced:
|
| trying to reduce TypeTables.AddType[constrained.NegativeInt, constrained.NegativeInt]
| failed since selector constrained.NegativeInt
| does not match case constrained.PositiveInt => constrained.NegativeInt match {
| case constrained.PositiveInt => constrained.PositiveInt
| case constrained.NegativeInt => Int
| }
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case constrained.NegativeInt => constrained.NegativeInt match {
| case constrained.NegativeInt => constrained.NegativeInt
| case constrained.PositiveInt => Int
| }
|
| longer explanation available when compiling with `-explain`
1 error found
1条答案
按热度按时间bkhjykvo1#
我认为如果你定义
AddType
作为匹配类型,你可以让你的第一个例子工作,因为你需要覆盖所有的情况。像这样: