Skip to content

Commit 3dabec8

Browse files
committed
more path-dependent GADT examples
1 parent d68559a commit 3dabec8

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

tests/pos/pdgadt-asmember.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Taken from https://github.com/lampepfl/dotty/pull/14754#issuecomment-1157427912.
2+
trait T[X]
3+
case object Foo extends T[Unit]
4+
5+
trait AsMember {
6+
type L
7+
val tl: T[L]
8+
}
9+
10+
def testMember(am: AsMember): Unit =
11+
am.tl match {
12+
case Foo => println(summon[am.L =:= Unit])
13+
case _ => ()
14+
}

tests/pos/pdgadt-nat-simpleadd.scala

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
trait Z
2+
trait S[N]
3+
4+
type of[A, B] = A & { type T = B }
5+
6+
trait Nat { type T }
7+
case class Zero() extends Nat { type T = Z }
8+
case class Succ[P](prec: Nat of P) extends Nat { type T = S[P] }
9+
10+
11+
type :=:[T, X] = T & { type R = X }
12+
13+
trait :+:[A, B] {
14+
type R
15+
}
16+
17+
object Addition {
18+
given AddZero[N]: :+:[Z, N] with {
19+
type R = N
20+
}
21+
22+
given AddSucc[M, N, X](using e: (M :+: N) :=: X): :+:[S[M], N] with {
23+
val e0: (M :+: N) :=: X = e
24+
type R = S[X]
25+
}
26+
}
27+
28+
object Proof {
29+
import Addition.given
30+
31+
def zeroAddN[N]: (Z :+: N) :=: N = summon
32+
33+
def nAddZero[N](n: Nat of N): (N :+: Z) :=: N = n match {
34+
case Zero() => zeroAddN[Z]
35+
case p: Succ[pn] =>
36+
val e0: (pn :+: Z) :=: pn = nAddZero[pn](p.prec)
37+
AddSucc(using e0)
38+
}
39+
}
40+

tests/pos/pdgadt-tupof.scala

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import scala.compiletime.ops.int.S
2+
3+
type sized[T, N <: Int] = T & { type Size = N }
4+
5+
abstract class TupOf[T, +A] {
6+
type Size <: Int
7+
}
8+
9+
object TupOf {
10+
given Empty[A]: TupOf[EmptyTuple, A] with {
11+
type Size = 0
12+
}
13+
14+
final given Cons[A, T <: Tuple, N <: Int](using p: T TupOf A sized N): TupOf[A *: T, A] with {
15+
val p0: T TupOf A sized N = p
16+
type Size = S[N]
17+
}
18+
}
19+
20+
enum Vec[N <: Int, +A]:
21+
case VecNil extends Vec[0, Nothing]
22+
case VecCons[N0 <: Int, A](head: A, tail: Vec[N0, A]) extends Vec[S[N0], A]
23+
24+
object Vec {
25+
import TupOf._
26+
def apply[A, T <: Tuple](xs: T)(using p: T TupOf A): Vec[p.Size, A] = p match {
27+
case _: TupOf.Empty[A] => VecNil
28+
case p1: TupOf.Cons[a, t, n] =>
29+
VecCons(xs.head, apply(xs.tail)(using p1.p0))
30+
}
31+
32+
def main(): Unit = {
33+
val vec1: Vec[3, Int] = VecCons(1, VecCons(2, VecCons(3, VecNil)))
34+
val vec2: Vec[3, Int] = Vec(1, 2, 3)
35+
}
36+
}
37+

0 commit comments

Comments
 (0)