F # Map Trouble - PullRequest
       12

F # Map Trouble

2 голосов
/ 11 апреля 2009

У меня проблемы с продвижением класса карты 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 [])

выбросить ключ не найден исключение?

1 Ответ

6 голосов
/ 11 апреля 2009

Я не повторяю это поведение (используя 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...