2009-04-11 132 views
2

我在麻煩F#的地圖課遇到麻煩。我創建了一個簡單的,天真的演算評價函數,F#地圖麻煩

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" 

明顯優化,這是改變列表的地圖,所以我想出了,

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 x = eval(prog, []) 

成功,但是,

let x2 = eval2(prog, Map []) 

拋出未發現異常的關鍵?

回答

6

我不瑞普這種行爲(使用F#1.9.6.2,它爲我的作品):

#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

嗯。現在,關閉並重新打開VS之後,我也無法重現它。 – chuckj 2009-04-11 20:04:07