type 'a t = { desc : 'a desc; meta : 'a }

and 'a desc =
  | Const of Const.t
  | Var of string
  | Lam of string list * 'a t
  | App of 'a t * 'a t list
  | Prim1 of Prim.op1 * 'a t
  | Prim2 of Prim.op2 * 'a t * 'a t
  | If of 'a t * 'a t * 'a t
  | Let of 'a binding * 'a t
  | Letrec of 'a binding list * 'a t
  | Tuple of 'a t list
  | Get of 'a t * int
  | Vect of 'a t * 'a t
  | VectGet of 'a t * 'a t
  | VectSet of 'a t * 'a t * 'a t
  | VectLength of 'a t
  | Ascribe of 'a t * Type.t
  | For of string * 'a t * 'a t * 'a t
  | Variant of string * 'a t list * Type.t
  | Match of 'a t * 'a pattern list * Type.t
  | Seq of 'a t list

and 'a binding = { name : string; term : 'a t }
and 'a pattern = { casename : string; args : string list; body : 'a t }

val pp :
  ?show_meta:bool ->
  (Format.formatter -> 'a -> unit) ->
  Format.formatter ->
  'a t ->
  unit
