2009-04-11 7 views
2

J'ai de la difficulté à gruger la classe Map de F #. J'ai créé une simple fonction d'évaluation de lambda-calcul naïf,F # Problème de la carte

type Name = string 
type Term = 
    | Var of Name 
    | Lit of int 
    | App of Term * Term 
    | Lam of Name * Term 

let rec lookup(v, e) = 
    match e with 
    | (v1, t)::tl   -> if v1 = v then t else lookup(v, tl) 
    | []     -> failwith "unknown variable %s" v 

let rec eval(x, e) = 
    match x with 
    | Var x    -> lookup(x, e) 
    | Lit x    -> Lit x 
    | App (Lam(v, f), t2) -> eval(f, ((v, t2)::e)) 
    | _     -> failwith "Invalid" 

L'optimisation évidente est de changer la liste à une carte, donc je suis venu avec,

let rec eval2(x, e: Map<Name,Term>) = 
    match x with 
    | Var v    -> e.[v] 
    | Lit l    -> x 
    | App (Lam (v, f), t) -> eval2(f, e.Add(v, t)) 
    | _     -> failwith "Invalid term" 

Compte tenu des valeurs,

let ident = Lam ("x", Var "x") 
let prog = App (ident, Lit 3) 

pourquoi le fait,

let x = eval(prog, []) 

réussir, mais,

let x2 = eval2(prog, Map []) 

jeter une clé non trouvée exception?

Répondre

6

Je ne REPRO pas ce comportement (en utilisant F # 1.9.6.2, il fonctionne pour moi):

#light 

type Name = string 
type Term = 
    | Var of Name 
    | Lit of int 
    | App of Term * Term 
    | Lam of Name * Term 

let rec eval2(x, e: Map<Name,Term>) = 
    match x with 
    | Var v    -> e.[v] 
    | Lit l    -> x 
    | App (Lam (v, f), t) -> eval2(f, e.Add(v, t)) 
    | _     -> failwith "Invalid term" 

let ident = Lam ("x", Var "x") 
let prog = App (ident, Lit 3) 
let x2 = eval2(prog, Map []) 
printfn "%A" x2 // Lit 3 
+0

Hmm. Maintenant, après avoir fermé et rouvert VS, je ne peux pas le reproduire non plus. – chuckj