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

Functional programming 在OCaml中实现类型方程生成器,functional-programming,ocaml,type-equivalence,Functional Programming,Ocaml,Type Equivalence,嗨,我正在尝试实现我最近在课堂上学习的类型方程生成器 但是,当我尝试使用上述方法实现ADD表达式时,我得到一个错误:“此表达式的类型为('a->'b->typ_eqn)list,但表达式的类型应为(typ*typ)list。” 附加两个或多个类型列表与(typ*typ)列表基本上是一样的吗 编辑: 我也尝试过这种方法,但这会给我一条错误消息: 此表达式具有类型(typ*typ)列表,但应为类型(typ*typ)的表达式 为什么这会突然发生变化?在您的第一个版本中,您编写了[gen_equatio

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

但是,当我尝试使用上述方法实现ADD表达式时,我得到一个错误:“此表达式的类型为('a->'b->typ_eqn)list,但表达式的类型应为(typ*typ)list。”

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

编辑:

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

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


为什么这会突然发生变化?

在您的第一个版本中,您编写了
[gen_equations(tenv,e1,TyInt)]
,但是
gen_equations
已经返回了一个列表。你可以试着只写
gen_方程tenv e1 TyInt
(注意从uncarried形式改为curried形式)

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

更新


在这两个版本中,您都是以非载波形式调用
gen_等式
,但它是以咖喱形式定义的。这样调用:
gen_方程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)]
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