匹配中的OCaml类型错误

时间:2015-08-22 17:16:51

标签: ocaml typeerror interpreter

我正在尝试建立一名翻译

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行和跟随(算术运算)?

1 个答案:

答案 0 :(得分:2)

从语法上讲,错误行看起来像是它上方match的延续。

你可以改变这个:

| Bool i -> match i with
            | 0 -> false
            | 1 -> true

到此:

| Bool i -> (match i with
            | 0 -> false
            | 1 -> true)

(作为旁注,这场比赛并非详尽无遗。)