在 OCaml 中实现类型方程生成器
Implementing type equation generator in OCaml
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)]
嗨,我正在尝试实现我最近在 class 中学到的类型方程生成器。
但是当我尝试使用上述方法实现 ADD 表达式时,我收到一条错误消息 "This expression has type ('a -> 'b -> typ_eqn) list, but an expression was expected of type (typ * typ) list."
追加两个或更多 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
我也试过这个方法,但是这给了我一条错误信息:
"This expression has type (typ * typ) list, but an expression was expected of type (typ * typ)."
为什么这突然期待不同的东西???
在您的第一个版本中,您编写了 [gen_equations (tenv, e1, TyInt)]
,但是 gen_equations
已经 returns 了一个列表。您可以尝试只写 gen_equations tenv e1 TyInt
(注意从未柯里化形式变为柯里化形式)。
在您的第二个版本中,您使用 ::
加入两个列表。但是 ::
用于将元素加入列表。你可以试试 l1 @ l2 @ l3
.
更新
在这两个版本中,您都以非柯里化形式调用 gen_equations
,但它是以柯里化形式定义的。像这样调用:gen_equations tenv e1 TyInt
.
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)]
嗨,我正在尝试实现我最近在 class 中学到的类型方程生成器。
但是当我尝试使用上述方法实现 ADD 表达式时,我收到一条错误消息 "This expression has type ('a -> 'b -> typ_eqn) list, but an expression was expected of type (typ * typ) list."
追加两个或更多 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
我也试过这个方法,但是这给了我一条错误信息:
"This expression has type (typ * typ) list, but an expression was expected of type (typ * typ)."
为什么这突然期待不同的东西???
在您的第一个版本中,您编写了 [gen_equations (tenv, e1, TyInt)]
,但是 gen_equations
已经 returns 了一个列表。您可以尝试只写 gen_equations tenv e1 TyInt
(注意从未柯里化形式变为柯里化形式)。
在您的第二个版本中,您使用 ::
加入两个列表。但是 ::
用于将元素加入列表。你可以试试 l1 @ l2 @ l3
.
更新
在这两个版本中,您都以非柯里化形式调用 gen_equations
,但它是以柯里化形式定义的。像这样调用:gen_equations tenv e1 TyInt
.