在OCaml中实现类型方程生成器

时间:2015-11-26 07:23:45

标签: functional-programming ocaml type-equivalence

type exp = 
  | CONST of int
  | VAR of var
  | ADD of exp * exp
  | SUB of exp * exp
  | ISZERO of exp
  | IF of exp * exp * exp
  | LET of var * exp * exp
  | PROC of var * exp
  | CALL of exp * exp
and var = string

type typ = TyInt | TyBool | TyFun of typ * typ | TyVar of tyvar
and tyvar = string

type typ_eqn = (typ * typ) list

module TEnv = struct
  type t = var -> typ
  let empty = fun _ -> raise (Failure "Type Env is empty")
  let extend (x,t) tenv = fun y -> if x = y then t else (tenv y)
  let find tenv x = tenv x
end

let rec gen_equations : TEnv.t -> exp -> typ -> typ_eqn 
=fun tenv e ty -> match e with
| CONST n -> [(ty, TyInt)]
| VAR x -> [(ty, TEnv.find tenv x)]
| ADD (e1,e2) -> [(ty, TyInt)]@
    [gen_equations (tenv, e1, TyInt)]@
    [gen_equations (tenv, e2, TyInt)]

嗨,我正试图实现我最近在课堂上学到的类型方程生成器。

但是当我尝试使用上述方法实现ADD表达式时,我收到一条错误消息,"此表达式具有类型(' a - >' b - > typ_eqn)列表,但预期表达类型(典型*典型)列表。"

是否附加了两个或更多typ_eqn类型列表与(typ * typ)列表基本相同?

编辑:

let rec gen_equations : TEnv.t -> exp -> typ -> typ_eqn 
=fun tenv e ty -> match e with
| CONST n -> [(ty, TyInt)]
| VAR x -> [(ty, TEnv.find tenv x)]
| ADD (e1,e2) -> let l1 = [(ty, TyInt)] in
    let l2 = gen_equations (tenv, e1, TyInt) in
    let l3 = gen_equations (tenv, e2, TyInt) in
    l1::l2::l3

我也尝试过这种方法,但这给了我一条错误信息:

"此表达式具有类型(典型*典型值)列表,但表达式需要类型(典型值*典型值)。"

为什么这突然间会有所不同?

1 个答案:

答案 0 :(得分:2)

在您的第一个版本中,您编写了[gen_equations (tenv, e1, TyInt)],但gen_equations已经返回了一个列表。你可以尝试只写gen_equations tenv e1 TyInt(注意从未加工到咖喱的形式改变)。

在您的第二个版本中,您使用::加入两个列表。但::用于将元素加入列表。您可以尝试l1 @ l2 @ l3

<强>更新

在这两个版本中,您都是以未经处理的形式调用gen_equations,但它是以咖喱形式定义的。像这样打电话:gen_equations tenv e1 TyInt