Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
(* $Id: mixev3.04.ml.txt,v 1.1 2005/02/24 01:45:32 garrigue Exp $ *)
(* Variables are common to lambda and expr *)
type var = [`Var of string]
let eval_var sub (`Var s as v : var) =
try List.assoc s sub with Not_found -> v
(* The lambda language: free variables, substitutions, and evaluation *)
type 'a lambda = [`Var of string | `Abs of string * 'a | `App of 'a * 'a]
let gensym = let n = ref 0 in fun () -> incr n; "_" ^ string_of_int !n
let eval_lambda eval_rec subst : 'a lambda -> [> 'a lambda] = function
#var as v -> eval_var subst v
| `App(l1, l2) ->
let l2' = eval_rec subst l2 in
begin match eval_rec subst l1 with
`Abs(s, body) ->
eval_rec [s,l2'] body
| l1' ->
`App (l1', l2')
end
| `Abs(s, l1) ->
let s' = gensym () in
`Abs(s', eval_rec ((s,`Var s')::subst) l1)
let rec eval1 subst = eval_lambda eval1 subst
(* The expr language of arithmetic expressions *)
type 'a expr =
[`Var of string | `Num of int | `Add of 'a * 'a | `Mult of 'a * 'a]
let map_expr f : 'a expr -> [> 'a expr] = function
#var | `Num _ as e -> e
| `Add(e1, e2) -> `Add (f e1, f e2)
| `Mult(e1, e2) -> `Mult (f e1, f e2)
let eval_expr eval_rec subst (e : 'a expr) : 'a =
match map_expr (eval_rec subst) e with
#var as v -> eval_var subst v
| `Add(`Num m, `Num n) -> `Num (m+n)
| `Mult(`Num m, `Num n) -> `Num (m*n)
| e -> e
let rec eval2 subst = eval_expr eval2 subst
(* The lexpr language, reunion of lambda and expr *)
type 'a lexpr = [ 'a lambda | 'a expr]
let eval_lexpr eval_rec subst : 'a lexpr -> [> 'a lexpr] = function
#lambda as x -> eval_lambda eval_rec subst x
| #expr as x -> eval_expr eval_rec subst x
let rec eval3 subst = eval_lexpr eval3 subst
(* A few examples:
eval1 [] (`App(`Abs("x",`Var"x"), `Var"y"));;
eval2 [] (`Add(`Mult(`Num 3, `Num 2), `Var"x"));;
eval3 [] (`Add(`App(`Abs("x",`Mult(`Var"x",`Var"x")),`Num 2), `Num 5));;
*)