type binop = | Plus | Minus | Times | Div [@@deriving eq, ord, show] type projection = | First | Second [@@deriving eq, ord, show] type t = | Var of Identifier.t | IntConst of int | Binop of t * binop * t | Pair of t * t | Proj of projection * t | Fun of Identifier.t * t | App of t * t [@@deriving eq, ord, show] let rec string_of_term = function | Var v -> "Var '" ^ v ^ "'" | IntConst n -> "IntConst(" ^ string_of_int n ^ ")" | Binop (a, b, c) -> "Binop (" ^ string_of_term a ^ ", " ^ (match b with | Plus -> "+" | Minus -> "-" | Times -> "*" | Div -> "/") ^ string_of_term c ^ ")" | Pair (a, b) -> "Pair (" ^ string_of_term a ^ ", " ^ string_of_term b ^ ")" | Proj (a, b) -> "Proj (" ^ (match a with | First -> "fst" | Second -> "snd") ^ ", " ^ string_of_term b ^ ")" | Fun (a, b) -> "Fun ('" ^ a ^ "', " ^ string_of_term b ^ ")" | App (a, b) -> "App (" ^ string_of_term a ^ ", " ^ string_of_term b ^ ")" ;;