sig
  module Type :
    sig
      type t = Nat | Arrow of T.Type.t * T.Type.t | Tvar of int
      val print : Pervasives.out_channel -> T.Type.t -> unit
      val to_string : T.Type.t -> string
    end
  module Ast :
    sig
      type t =
          Num of int
        | Var of string
        | Op of Op.t * T.Ast.t * T.Ast.t
        | Ifz of T.Ast.t * T.Ast.t * T.Ast.t
        | Let of string * T.Ast.t * T.Ast.t
        | App of T.Ast.t * T.Ast.t
        | Fun of string * T.Type.t * T.Ast.t
        | Fix of string * T.Type.t * T.Ast.t
      val erase : T.Ast.t -> S.Ast.t
    end
  module Reader :
    sig
      val from_chan : Pervasives.in_channel -> T.Ast.t
      val from_string : string -> T.Ast.t
    end
  module Top :
    sig
      val loop : (T.Type.t Env.t -> T.Ast.t -> T.Type.t) -> unit
      val loop_eval :
        (T.Type.t Env.t -> T.Ast.t -> T.Type.t) ->
        (Pervasives.out_channel -> '-> unit) ->
        ('Env.t -> T.Ast.t -> 'a) -> unit
    end
end