%%% Examples of recursive types NAT = mu [a] plus one a. zero = fold (inl unit). succ = lam [x] fold (inr x). %query 1 * chk zero NAT. %query 1 * chk succ (arrow NAT NAT). double = letv (coerce (fold (inl unit)) NAT) [zero] letv (coerce (lam [x] fold (inr x)) (arrow NAT NAT)) [succ] fix [d] lam [x] cases (unfold x) ([x0] zero) ([x1] app succ (app succ (app d x1))). %query 1 * C : chk double (arrow NAT NAT). double2 = letv (coerce (fold (inl unit)) NAT) [zero] letv (coerce (lam [x] fold (inr x)) (arrow NAT NAT)) [succ] letv (coerce (fix [d] lam [x] cases (unfold x) ([x0] zero) ([x1] app succ (app succ (app d x1)))) (arrow NAT NAT)) [double] app double (app succ (app succ zero)). %query 1 * chk double2 NAT. %query 1 * eval double2 V. LIST = [t] mu [a] plus one (cross t a). nil = fold (inl unit). cons = lam [p] fold (inr p). %query 1 * {t:tp} chk nil (LIST t). %query 1 * {t:tp} chk cons (arrow (cross t (LIST t)) (LIST t)). caselist = [t:tp] letv (coerce (fold (inl unit)) (LIST t)) [nil] letv (coerce (lam [p] fold (inr p)) (arrow (cross t (LIST t)) (LIST t))) [cons] lam [x] lam [xn] lam [xc] cases (unfold x) ([u] xn) ([p] app xc p). %query 1 * C : {t:tp} {a:tp} chk (caselist t) (arrow (LIST t) (arrow a (arrow (arrow (cross t (LIST t)) a) a))). %%% Examples of abstract types => = arrow. %infix right 10 =>. * = cross. %infix right 11 *. , = pair'. %infix right 9 ,. @ = app'. %infix left 10 @. integers = exists [int] (nat => int) % toInt * (int * int => int) % plus * (int * int => int) % minus * (int => nat * nat). % fromInt 0-n or n-0 int1 = pack' (nat * nat) (letv' (fix' [plus] lam' [x] lam' [y] case' x y [x'] s' (plus @ x' @ y)) [plus] letv' (fix' [norm] lam' [x] lam' [y] case' x (x , y) [x'] case' y (x , y) [y'] norm @ x' @ y') [norm] (lam' [n] (n , z')), (lam' [ij] (plus @ (fst' (fst' ij)) @ (fst' (snd' ij)), plus @ (snd' (fst' ij)) @ (snd' (snd' ij)))), (lam' [ij] (plus @ (fst' (fst' ij)) @ (snd' (snd' ij)), plus @ (fst' (snd' ij)) @ (snd' (fst' ij)))), (lam' [i] (norm @ (fst' i) @ (snd' i)))) : tm integers. test1 = unpack' int1 [int] [ix] letv' (fst' ix) [toInt] letv' (fst' (snd' ix)) [add] letv' (fst' (snd' (snd' ix))) [subtract] letv' (snd' (snd' (snd' ix))) [fromInt] fromInt @ (toInt @ s' (s' (s' z'))). %query 1 * eval' test1 V. %{ Next is a type error test1' = unpack' int1 [int] [ix] letv' (fst' ix) [toInt] letv' (fst' (snd' ix)) [add] letv' (fst' (snd' (snd' ix))) [subtract] letv' (snd' (snd' (snd' ix))) [fromInt] fst' (toInt @ s' (s' (s' z'))). }% test2 = unpack' int1 [int] [ix] letv' (fst' ix) [toInt] letv' (fst' (snd' ix)) [add] letv' (fst' (snd' (snd' ix))) [subtract] letv' (snd' (snd' (snd' ix))) [fromInt] fromInt @ (subtract @ (toInt @ (s' z') , toInt @ (s' (s' (s' z'))))). %query 1 * eval' test2 V.