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

2023-11-30

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 *typ) 列表类型”。

附加两个或多个typ_eqn类型列表与(typ *typ)列表基本上是一样的吗?

edit:

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

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

“此表达式具有类型 (typ *typ) 列表,但表达式应为 (typ *typ) 类型。”

为什么突然期待一些不同的东西???


在你的第一个版本中你写[gen_equations (tenv, e1, TyInt)], but gen_equations已经返回一个列表。你可以尝试只写gen_equations tenv e1 TyInt(注意从非柯里化形式到柯里化形式的变化)。

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

Update

在这两个版本中,您都在调用gen_equations以非柯里化形式,但它是以柯里化形式定义的。像这样调用:gen_equations tenv e1 TyInt.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 OCaml 中实现类型方程生成器 的相关文章

随机推荐