Closed
Description
I've been trying to use match types to implement a type-level binary nat type.
Here is the code I would ideally like to work:
object Main {
enum BinNat {
case Zero
// 2n + 1
case Odd[N <: BinNat](n: N)
// 2(n + 1)
case Even[N <: BinNat](n: N)
}
import BinNat._
type Inc[N <: BinNat] <: BinNat =
N match {
case Zero.type => Odd[Zero.type]
case Odd[n] => Even[n]
case Even[n] => Odd[Inc[n]]
}
def inc(b: BinNat): Inc[b.type] =
b match {
case Zero => Odd(Zero)
case Odd(n) => Even(n)
case Even(n) =>
// 2(n + 1) + 1 = 2(inc(n)) + 1
Odd(inc(n))
}
}
The error message I get is:
[error] -- [E007] Type Mismatch Error: /Users/oscar/oss/dotty_tests/src/main/scala/Main.scala:30:22
[error] 30 | case Zero => Odd(Zero)
[error] | ^^^^^^^^^
[error] | Found: Main.BinNat
[error] | Required: Main.Inc[Main.BinNat(b)]
[error] -- [E007] Type Mismatch Error: /Users/oscar/oss/dotty_tests/src/main/scala/Main.scala:31:25
[error] 31 | case Odd(n) => Even(n)
[error] | ^^^^^^^
[error] | Found: Main.BinNat
[error] | Required: Main.Inc[Main.BinNat(b)]
[error] -- [E007] Type Mismatch Error: /Users/oscar/oss/dotty_tests/src/main/scala/Main.scala:34:11
[error] 34 | Odd(inc(n))
[error] | ^^^^^^^^^^^
[error] | Found: Main.BinNat
[error] | Required: Main.Inc[Main.BinNat(b)]
[error] three errors found
I have tried several different variants (using manual sealed trait/case classes, matching on _: Zero.type
, explicitly adding type annotations in the def inc
method... each seemed to trigger different errors and I couldn't find any that worked.
expectation
I'd like it to compile, or suggest a better action to take in the error message