|
| 1 | +:NewDefs |
| 2 | + |
| 3 | +abstract class HOA[type T]: Lit[T] | Abs[?,?] | App[?,T] |
| 4 | +class Lit[A](x: A) extends HOA[A] |
| 5 | +class Abs[A, B](f: A => HOA[B]) extends HOA[A => B] |
| 6 | +class App[A, B](f: HOA[A => B], x: HOA[A]) extends HOA[B] |
| 7 | +//│ abstract class HOA[T]: Abs[nothing, ?] | App[?, T] | Lit[T] |
| 8 | +//│ class Lit[A](x: A) extends HOA |
| 9 | +//│ class Abs[A, B](f: A -> HOA[B]) extends HOA |
| 10 | +//│ class App[A, B](f: HOA[A -> B], x: HOA[A]) extends HOA |
| 11 | + |
| 12 | +fun eval: forall 'T : HOA['T] -> 'T |
| 13 | +fun eval(e: HOA['T]): e.T = if e is |
| 14 | + Lit(x) then x |
| 15 | + Abs(f) then x => eval(f(x)) |
| 16 | + App(f, x) then eval(f)(eval(x)) |
| 17 | +//│ fun eval: forall 'T 'a. (e: HOA['T]) -> 'a |
| 18 | +//│ fun eval: forall 'T0. HOA['T0] -> 'T0 |
| 19 | +//│ where |
| 20 | +//│ 'T <: 'a | ~(nothing -> ??B) |
| 21 | + |
| 22 | +eval(App(Abs(x => Lit(x + 1)), Lit(1))) |
| 23 | +//│ Int |
| 24 | +//│ res |
| 25 | +//│ = 2 |
| 26 | + |
| 27 | +:e |
| 28 | +eval(App(Abs(x => Lit(x + 1)), Lit(true))) |
| 29 | +//│ ╔══[ERROR] Type mismatch in application: |
| 30 | +//│ ║ l.28: eval(App(Abs(x => Lit(x + 1)), Lit(true))) |
| 31 | +//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 32 | +//│ ╟── reference of type `true` is not an instance of `Int` |
| 33 | +//│ ║ l.28: eval(App(Abs(x => Lit(x + 1)), Lit(true))) |
| 34 | +//│ ║ ^^^^ |
| 35 | +//│ ╟── Note: constraint arises from reference: |
| 36 | +//│ ║ l.28: eval(App(Abs(x => Lit(x + 1)), Lit(true))) |
| 37 | +//│ ║ ^ |
| 38 | +//│ ╟── Note: type parameter A is defined at: |
| 39 | +//│ ║ l.6: class App[A, B](f: HOA[A => B], x: HOA[A]) extends HOA[B] |
| 40 | +//│ ╙── ^ |
| 41 | +//│ Int |
| 42 | +//│ res |
| 43 | +//│ = 2 |
| 44 | + |
| 45 | +abstract class HList[type T]: HNil | HCons[?,?] |
| 46 | +module HNil extends HList[[]] |
| 47 | +class HCons[type A, type B](h: A, t: HList[B]) extends HList[[A, B]] |
| 48 | +//│ abstract class HList[T]: HCons[anything, ?] | HNil |
| 49 | +//│ module HNil extends HList |
| 50 | +//│ class HCons[A, B](h: A, t: HList[B]) extends HList |
| 51 | + |
| 52 | +// FIXME |
| 53 | +fun hhead : HList[['A, 'B]] -> 'A |
| 54 | +fun hhead[A, B](xs: HList[[A, B]]): A = |
| 55 | + if xs is HCons(h, t) then h : xs.A else error |
| 56 | +//│ ╔══[ERROR] Type mismatch in type ascription: |
| 57 | +//│ ║ l.55: if xs is HCons(h, t) then h : xs.A else error |
| 58 | +//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 59 | +//│ ╟── type `anything` does not match type `A | ~??A` |
| 60 | +//│ ║ l.55: if xs is HCons(h, t) then h : xs.A else error |
| 61 | +//│ ║ ^^ |
| 62 | +//│ ╟── Note: method type parameter A is defined at: |
| 63 | +//│ ║ l.54: fun hhead[A, B](xs: HList[[A, B]]): A = |
| 64 | +//│ ╙── ^ |
| 65 | +//│ fun hhead: forall 'A 'B. (xs: HList[['A, 'B]]) -> 'A |
| 66 | +//│ fun hhead: forall 'A0 'B0. HList[['A0, 'B0]] -> 'A0 |
| 67 | + |
| 68 | +// FIXME |
| 69 | +fun htail : HList[['A, 'B]] -> HList['B] |
| 70 | +fun htail[A, B](xs: HList[[A, B]]): HList[B] = |
| 71 | + if xs is HCons(h, t) then t : HList[xs.B] else error |
| 72 | +//│ ╔══[ERROR] Type mismatch in type ascription: |
| 73 | +//│ ║ l.71: if xs is HCons(h, t) then t : HList[xs.B] else error |
| 74 | +//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 75 | +//│ ╟── type `B` does not match type `nothing` |
| 76 | +//│ ║ l.70: fun htail[A, B](xs: HList[[A, B]]): HList[B] = |
| 77 | +//│ ║ ^ |
| 78 | +//│ ╟── Note: constraint arises from type selection: |
| 79 | +//│ ║ l.71: if xs is HCons(h, t) then t : HList[xs.B] else error |
| 80 | +//│ ╙── ^^ |
| 81 | +//│ fun htail: forall 'A 'B. (xs: HList[['A, 'B]]) -> HList['B] |
| 82 | +//│ fun htail: forall 'A0 'B0. HList[['A0, 'B0]] -> HList['B0] |
| 83 | + |
| 84 | +fun hlen : HList['A] -> Int |
| 85 | +fun hlen(xs: HList['a]): Int = |
| 86 | + if xs is HCons(h, t) then 1 + hlen(t) else 0 |
| 87 | +//│ fun hlen: forall 'a. (xs: HList['a]) -> Int |
| 88 | +//│ fun hlen: forall 'A. HList['A] -> Int |
0 commit comments