mode U structural :> L
mode L linear

type nat[k] = +{'zero : 1, 'succ : <nat[k]>}
type list[m k] = +{'nil : 1, 'cons : <nat[k]> * <list[m k]>}

decl append (l1 : list[L U]) (l2 : list[L U]) : list[L U]
decl append (l1 : list[L L]) (l2 : list[L L]) : list[L L]
decl append (l1 : list[U U]) (l2 : list[U U]) : list[U U]
decl append (l1 : list[U U]) (l2 : list[L U]) : list[L U]

defn append l1 l2 = match l1 with
| 'nil() => l2
| 'cons(<hd>, <tl>) => 'cons(<hd>, <append tl l2>)
(* end *)

decl map (f : [U] up[L] (nat[L] -> nat[L])) (l : list[L L]) : list[L L]
decl map (f : [U] up[U] (nat[U] -> nat[U])) (l : list[L U]) : list[L U]
decl map (f : [U] up[U] (nat[U] -> nat[U])) (l : list[U U]) : list[L U]

defn map f l = match l with
| 'nil() => 'nil()
| 'cons(<x>, <xs>) => 'cons(<f.force x>, <map f xs>)
(* end *)

