java的静态类型检查_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

(* raise this exception when the program is determined to be ill-typed *)

exception TypeError

(* type *)

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

and tyvar = string

(* type equations are represented by a list of "equalities" (ty1 = ty2) *)

type typ_eqn = (typ * typ) list

(* generate a fresh type variable *)

let tyvar_num = ref 0

let fresh_tyvar () = (tyvar_num := !tyvar_num + 1; (TyVar ("t" ^ string_of_int !tyvar_num)))

(* type environment : var -> type *)

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

(* substitution *)

module Subst = struct

type t = (tyvar * typ) list

let empty = []

let find x subst = List.assoc x subst

(* walk through the type, replacing each type variable by its binding in the substitution *)

let rec apply : typ -> t -> typ

=fun typ subst ->

match typ with

| TyInt -> TyInt

| TyBool -> TyBool

| TyFun (t1,t2) -> TyFun (apply t1 subst, apply t2 subst)

| TyVar x ->

try find x subst

with _ -> typ

(* add a binding (tv,ty) to the subsutition and propagate the information *)

let extend tv ty subst =

(tv,ty) :: (List.map (fun (x,t) -> (x, apply t [(tv,ty)])) subst)

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) ->

let l1 = [(ty, TyInt)] in

let l2 = gen_equations tenv e1 TyInt in

let l3 = gen_equations tenv e2 TyInt in

l1@l2@l3

| SUB (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

| ISZERO e ->

let l1 = [(ty, TyBool)] in

let l2 = gen_equations tenv e TyInt in

l1@l2

| IF (e1,e2,e3) ->

let l1 = gen_equations tenv e1 TyBool in

let l2 = gen_equations tenv e2 ty in

let l3 = gen_equations tenv e3 ty in

l1@l2@l3

| LET (x,e1,e2) ->

let t = fresh_tyvar () in

let l1 = gen_equations tenv e1 t in

let l2 = gen_equations (TEnv.extend (x,t) tenv) e2 ty in

l1@l2

| PROC (x,e) ->

let t1 = fresh_tyvar () in

let t2 = fresh_tyvar () in

let l1 = [(ty, TyFun (t1,t2))] in

let l2 = gen_equations (TEnv.extend (x,t1) tenv) e t2 in

l1@l2

| CALL (e1,e2) ->

let t = fresh_tyvar () in

let l1 = gen_equations tenv e1 (TyFun (t,ty)) in

let l2 = gen_equations tenv e2 t in

l1@l2

| _ -> raise TypeError

(* this is where the error comes up *)

let solve : typ_eqn -> Subst.t

=fun eqn -> unifyall eqn Subst.empty

let rec unify : typ -> typ -> Subst.t -> Subst.t

=fun t1 t2 s -> match (t1,t2) with

| (TyInt,TyInt) -> s

| (TyBool,TyBool) -> s

| (t,TyVar a) -> unify (TyVar a) t s

| (TyVar t1,t2) -> Subst.extend t1 t2 s

| (TyFun (t1,t2), TyFun (t1',t2')) ->

let s' = unify t1 t1' s in

let t1'' = Subst.apply t2 s' in

let t2'' = Subst.apply t2' s' in

unify t1'' t2'' s'

let rec unifyall : typ_eqn -> Subst.t -> Subst.t

=fun eqn s -> match eqn with

| [] -> s

| (t1,t2)::u ->

let s' = unify (Subst.apply t1 s) (Subst.apply t2 s) s in

unifyall u s'

let typeof : exp -> typ

=fun exp ->

let new_tv = fresh_tyvar () in

let eqns = gen_equations TEnv.empty exp new_tv in

let subst = solve eqns in

let ty = Subst.apply new_tv subst in

ty

这是来自OCaml中的过程函数的静态类型检查器 . 除“解决”功能部分外,所有功能都运行良好 . 错误说,

错误:此表达式的类型为typ_eqn / 3404 =(typ / 3398 * typ / 3398)列表但是表达式类型为typ_eqn / 3179 =(typ / 3173 * typ / 3173)列表类型typ / 3398与type typ / 3173

/ mark旁边的那个大数字是什么?为什么不运作?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值