Skip to content

Instantly share code, notes, and snippets.

@EduardoRFS
Last active September 22, 2025 21:08
Show Gist options
  • Save EduardoRFS/6c34bf5d004b0b11b9fe6fd82ead78ec to your computer and use it in GitHub Desktop.
Save EduardoRFS/6c34bf5d004b0b11b9fe6fd82ead78ec to your computer and use it in GitHub Desktop.
type index = int
type term =
| T_var of index
| T_lambda of term lazy_t
| T_apply of term lazy_t * term lazy_t
let rec shift ~by ~depth term =
match term with
| T_var var -> (
match var <= depth with true -> T_var (by + var) | false -> T_var var)
| T_lambda body ->
let body =
let depth = 1 + depth in
shift_lazy ~by ~depth body
in
T_lambda body
| T_apply (funct, arg) ->
let funct = shift_lazy ~by ~depth funct in
let arg = shift_lazy ~by ~depth arg in
T_apply (funct, arg)
and shift_lazy ~by ~depth term = lazy (shift ~by ~depth (Lazy.force term))
let shift ~by term = shift ~by ~depth:0 term
let rec subst ~to_ ~depth term =
match term with
| T_var var -> (
let to_ = Lazy.force to_ in
match var = depth with true -> shift ~by:depth to_ | false -> T_var var)
| T_lambda body ->
let body =
let depth = 1 + depth in
subst_lazy ~to_ ~depth body
in
T_lambda body
| T_apply (funct, arg) ->
let funct = subst_lazy ~to_ ~depth funct in
let arg = subst_lazy ~to_ ~depth arg in
T_apply (funct, arg)
and subst_lazy ~to_ ~depth term = lazy (subst ~to_ ~depth (Lazy.force term))
let subst ~to_ term = subst ~to_ ~depth:0 term
let rec eval term =
match term with
| T_var var -> T_var var
| T_lambda body ->
let body = eval_lazy body in
T_lambda body
| T_apply (funct, arg) -> (
let funct = eval_lazy funct in
let arg = eval_lazy arg in
match Lazy.force funct with
| T_lambda body ->
let body = Lazy.force body in
eval @@ subst ~to_:arg body
| T_var _ | T_apply (_, _) -> T_apply (funct, arg))
and eval_lazy term = lazy (eval (Lazy.force term))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment