我正在尝试建立一名翻译
type ide = string;;
type integer = int;;
(*Eccezioni*)
exception WrongMatchException;;
exception EmptyEnvException;;
exception UnboundRecordException;;
type exp =
| Ide of ide (*Identificatore*)
| Int of int (*Valori Interi*)
| Bool of int (*Valori Booleani*)
| Add of exp * exp (*Operatori Matematici*)
| Sub of exp * exp
| Mul of exp * exp
| Eq of exp * exp
| Leq of exp * exp
| And of exp * exp (*Operatori Logici*)
| Or of exp * exp
| Not of exp
| Fun of ide * exp (*Funzione con un parametro, non ricorsiva*)
| IfThenElse of exp * exp * exp (*Classico If Then Else *)
| LetIn of ide * exp * exp (*Blocco Let*)
| Function of ide * exp (*Applicazione funzionale Ide(E)*)
| CreateTuple of ide * exp (*Espressione Tupla*)
| GetIndex of exp * integer (*Accesso Elemento Tupla*)
| GetFirstN of exp * integer (* Seleziona elementi Tupla*)
| TupleEquals of exp * exp (*Confronto tra tuple*)
| Map of ide * exp (*Applica funzione ad elementi tupla*)
;;
(*Elementi di una tupla*)
type elts =
| Elemento of exp
| Lista of exp list
;;
(* the empty environment *)
(* emptyEnv: 'a -> 'b *)
let emptyEnv = fun x -> raise EmptyEnvException;;
let emptyFunEnv = fun x -> raise EmptyEnvException;;
(*bind: ('a -> 'b) -> ide -> exp -> (ide -> exp ) *)
let bind env (variable: ide) value = fun y ->
if variable = y then value else env y;;
let rec eval (expression: exp) env funenv =
match expression with
| Int i -> i
| Ide i -> env i
| Bool i -> match i with
| 0 -> false
| 1 -> true
| Add (e1, e2) -> (eval e1 env funenv) + (eval e2 env funenv)
| Sub (e1, e2) -> (eval e1 env funenv) - (eval e2 env funenv)
| Mul (e1, e2) -> (eval e1 env funenv) * (eval e2 env funenv)
| Eq (e1, e2) -> (eval e1 env funenv) = (eval e2 env funenv)
| Leq (e1, e2) -> (eval e1 env funenv) <= (eval e2 env funenv)
| And (e1, e2) -> if eval e1 env funenv then eval e2 env funenv else false
| Or (e1, e2) -> if eval e1 env funenv then eval e2 envfunenv else false
| Not (e1) -> if (eval e1 env funenv) then false else true
(*| Fun (funName, arg) -> (*Chiamata di funzione*)
let value = eval arg env in
let (param, body, ambiente) = fenv funName in
let env1 = bind env param value in
eval body env1 fenv *)
| IfThenElse (e1, e2, e3) -> if eval e1 env funenv then eval e2 env funenv
else eval e3 env funenv
| Let (id, value, body) -> let value = eval id env funenv in
let env1 = bind env id value in
eval body env1 funenv
| GetIndex (id, i) -> (eval id env funenv)[eval i env funenv]
| GetFirstN (exp, i) -> (eval exp env funenv) fst (eval i env funenv)
| TupleEquals (exp1, exp2) -> (eval exp1 env funenv) = (eval exp2 env funenv)
| Map (funx, exp) -> funx @ (eval exp env funenv)
| _ -> raise WrongMatchException
;;
当我尝试编译此代码时,输出为
File "progetto.ml", line 53, characters 3-15:
Error: This pattern matches values of type exp
but a pattern was expected which matches values of type int
第53行是
| Add (e1, e2) -> (eval e1 env funenv) + (eval e2 env funenv)
我不明白为什么会产生错误。 Ide i是一个字符串,而不是整数。为什么错误没有出现在那里,只是在53行和跟随(算术运算)?
答案 0 :(得分:2)
从语法上讲,错误行看起来像是它上方match
的延续。
你可以改变这个:
| Bool i -> match i with
| 0 -> false
| 1 -> true
到此:
| Bool i -> (match i with
| 0 -> false
| 1 -> true)
(作为旁注,这场比赛并非详尽无遗。)