// Create a list by iterating `f` `n` times: letrec iterate = \f x. { Z -> [] ; S n -> (x :: iterate f (f x) n) }; // Use the iterate function to count to 10: let countTo = iterate S 1 in countTo 10; // Append two lists together: letrec append = \xs ys. { [] -> ys ; (x :: xs) -> (x :: append xs ys) } xs; // Reverse a list: letrec reverse = { [] -> [] ; (x :: xs) -> append (reverse xs) [x] }; // Now we can reverse `"reverse"`: reverse "reverse"; // Calculating `3 + 2` with the help of Church-encoded numerals: let Sf = \n f x. f (n f x) ; plus = \x. x Sf in plus (\f x. f (f (f x))) (\f x. f (f x)) S Z; letrec undefined = undefined; // This expression would loop forever, but `callcc` saves the day! S (callcc \k. undefined (k Z)); // And if it wasn't clear, this is what the `Char` constructor does: { Char c -> Char (S c) } 'a; // (it outputs `'b`) // Here are a few expressions which don't typecheck but are handy for debugging the evaluator // (you can run them using `:check off off`: /* let D = \x. x x; F = \f. f (f y) in D (F \x. x); // y y let T = \f x. f (f x) in (\f x. T (T (T (T T))) f x) (\x. x) y; // y (\x y z. x y) y; // λy' z. y y' */