Created
January 10, 2023 18:40
-
-
Save johnynek/fd74bef5e4aab13bea0c07dcd553a8e5 to your computer and use it in GitHub Desktop.
Attempt to use scala match types to make a Nat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dev.posco.nui | |
import scala.compiletime.{erasedValue, error, ops, requireConst} | |
object NatExample { | |
sealed trait Nat | |
object Nat { | |
case object Zero extends Nat | |
case class Succ[N <: Nat](prev: N) extends Nat | |
given zero: Zero.type = Zero | |
given buildSucc[N <: Nat](using n: N): Succ[N] = | |
Succ(n) | |
def value[N <: Nat](using n: N): N = n | |
type FromInt[I <: Int] <: Nat = I match { | |
case 0 => Zero.type | |
case _ => | |
// commented out trying to get fromInt to work | |
// ops.int.<[I, 0] match { | |
// case true => Nothing | |
// case false => | |
Succ[FromInt[ops.int.-[I, 1]]] | |
// } | |
} | |
inline def fromInt[I <: Int](inline i: I): FromInt[I] = { | |
requireConst(i) | |
inline i match { | |
case _: 0 => Zero | |
case _ => | |
inline if i < 0 then error("cannot convert negative to Nat") | |
else { | |
// obviously the cast is bad | |
val prev: ops.int.-[I, 1] = (i - 1).asInstanceOf[ops.int.-[I, 1]] | |
// this fails because prev is not a const even though this all should be inlined. | |
Succ(fromInt[ops.int.-[I, 1]](prev)) | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment