簡體   English   中英

OCaml 函數式語言的表達式錯誤

[英]Expression Error on OCaml functional language

我在 OCaml 中定義了一個原始類型,這是一個家庭作業。 一切正常,但我在實現 Dict 類型時遇到錯誤。 編碼:

type ide = string;;

type exp = Eint of int | Ebool of bool | Den of ide | Prod of exp * exp | Sum of exp * exp | Diff of exp * exp |
    Eq of exp * exp | Minus of exp | IsZero of exp | Or of exp * exp | And of exp * exp | Not of exp |
    Ifthenelse of exp * exp * exp | Let of ide * exp * exp | Fun of ide * exp | FunCall of exp * exp |
    Letrec of ide * exp * exp| Dict of (ide * exp) list;;

type 't env = ide -> 't;;
let emptyenv (v : 't) = function x -> v;;
let applyenv (r : 't env) (i : ide) = r i;;
let bind (r : 't env) (i : ide) (v : 't) = function x -> if x = i then v else applyenv r x;;

type evT = Int of int | Bool of bool | Unbound | FunVal of evFun | RecFunVal of ide * evFun | DictVal of (ide * evT) list
and evFun = ide * exp * evT env;;

let typecheck (s : string) (v : evT) : bool = match s with
    "int" -> (match v with
        Int(_) -> true |
        _ -> false) |
    "bool" -> (match v with
        Bool(_) -> true |
        _ -> false) |
    _ -> failwith("not a valid type");;


let prod x y = if (typecheck "int" x) && (typecheck "int" y)
    then (match (x,y) with
        (Int(n),Int(u)) -> Int(n*u))
    else failwith("Type error");;

let sum x y = if (typecheck "int" x) && (typecheck "int" y)
    then (match (x,y) with
        (Int(n),Int(u)) -> Int(n+u))
    else failwith("Type error");;

let diff x y = if (typecheck "int" x) && (typecheck "int" y)
    then (match (x,y) with
        (Int(n),Int(u)) -> Int(n-u))
    else failwith("Type error");;

let eq x y = if (typecheck "int" x) && (typecheck "int" y)
    then (match (x,y) with
        (Int(n),Int(u)) -> Bool(n=u))
    else failwith("Type error");;

let minus x = if (typecheck "int" x) 
    then (match x with
        Int(n) -> Int(-n))
    else failwith("Type error");;

let iszero x = if (typecheck "int" x)
    then (match x with
        Int(n) -> Bool(n=0))
    else failwith("Type error");;

let vel x y = if (typecheck "bool" x) && (typecheck "bool" y)
    then (match (x,y) with
        (Bool(b),Bool(e)) -> (Bool(b||e)))
    else failwith("Type error");;

let et x y = if (typecheck "bool" x) && (typecheck "bool" y)
    then (match (x,y) with
        (Bool(b),Bool(e)) -> Bool(b&&e))
    else failwith("Type error");;

let non x = if (typecheck "bool" x)
    then (match x with
        Bool(true) -> Bool(false) |
        Bool(false) -> Bool(true))
    else failwith("Type error");;


let rec eval (e : exp) (r : evT env) : evT = match e with

    Dict(pairs) -> DictVal(evalDictList pairs r) |
    Eint n -> Int n |
    Ebool b -> Bool b |
    IsZero a -> iszero (eval a r) |
    Den i -> applyenv r i |
    Eq(a, b) -> eq (eval a r) (eval b r) |
    Prod(a, b) -> prod (eval a r) (eval b r) |
    Sum(a, b) -> sum (eval a r) (eval b r) |
    Diff(a, b) -> diff (eval a r) (eval b r) |
    Minus a -> minus (eval a r) |
    And(a, b) -> et (eval a r) (eval b r) |
    Or(a, b) -> vel (eval a r) (eval b r) |
    Not a -> non (eval a r) |
    Ifthenelse(a, b, c) -> 
        let g = (eval a r) in
            if (typecheck "bool" g) 
                then (if g = Bool(true) then (eval b r) else (eval c r))
                else failwith ("nonboolean guard") |
    Let(i, e1, e2) -> eval e2 (bind r i (eval e1 r)) |
    Fun(i, a) -> FunVal(i, a, r) |
    FunCall(f, eArg) -> 
        let fClosure = (eval f r) in
            (match fClosure with
                FunVal(arg, fBody, fDecEnv) -> 
                    eval fBody (bind fDecEnv arg (eval eArg r)) |
                RecFunVal(g, (arg, fBody, fDecEnv)) -> 
                    let aVal = (eval eArg r) in
                        let rEnv = (bind fDecEnv g fClosure) in
                            let aEnv = (bind rEnv arg aVal) in
                                eval fBody aEnv |
                _ -> failwith("non functional value")) |
        Letrec(f, funDef, letBody) ->
                (match funDef with
                    Fun(i, fBody) -> let r1 = (bind r f (RecFunVal(f, (i, fBody, r)))) in
                                                    eval letBody r1 |
                    _ -> failwith("non functional def"))            

    and evalDictList (pairs : (ide * exp) list) (r : evT env) : (ide * evT) list = match pairs with
        [ ] -> [ ] |
        (key,value) :: other -> (key, eval value r) :: evalDictList other r;;

一切正常,但是當我這樣做時:

let mydict = Dict("test", Eint 2);;

Dict("test", Eint 2);;

我收到此錯誤:錯誤:此表達式的類型為 'a * 'b,但期望表達式為 (ide * exp) 列表類型。

這個作業包括為具有上述原始類型的語言編寫一個基本的解釋器。

該錯誤比實際需要的更籠統和模糊,但直接指向問題。 如果我將錯誤中的類型變量'a'b替換為實際類型,您可能會立即看到它:

錯誤:此表達式的類型為 ide * exp,但應為 (ide * exp) 列表類型的表達式。

也就是說,您給Dict一個元組(某事物),但它期望一個元組列表(具有某些特定類型),因為它被定義為Dict of (ide * exp) list

將元組包裝在列表中將使其編譯:

let mydict = Dict [("test", Eint 2)];;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM