Skip to content

Instantly share code, notes, and snippets.

@Hirrolot
Last active January 11, 2024 23:36
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Hirrolot/f1b0854c2aa78085b4ed701a9e0dd4ed to your computer and use it in GitHub Desktop.
Save Hirrolot/f1b0854c2aa78085b4ed701a9e0dd4ed to your computer and use it in GitHub Desktop.
A five-line lambda calculus with OCaml's polymorphic variants
let rec eval = function
| `Appl (m, n) -> (
let n' = eval n in
match eval m with `Lam f -> eval (f n') | m' -> `Appl (m', n'))
| (`Lam _ | `Var _) as t -> t
let sprintf = Printf.sprintf
(* Print a given term using De Bruijn levels. *)
let rec pp lvl = function
| `Lam f -> sprintf "(λ . %s)" (pp (lvl + 1) (f (`Var lvl)))
| `Appl (m, n) -> sprintf "(%s%s)" (pp lvl m) (pp lvl n)
| `Var lvl -> sprintf "%d" lvl
let () =
let s =
`Lam
(fun x ->
`Lam (fun y -> `Lam (fun z -> `Appl (`Appl (x, z), `Appl (y, z)))))
in
let k = `Lam (fun x -> `Lam (fun _ -> x)) in
let i = `Appl (`Appl (s, k), k) in
(* (λ . (λ . 0)) *)
print_endline (pp 0 (eval (`Appl (i, k))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment