Đầu hôm nay tôi gặp phải một hạn chế của F # trích dẫn, và hỏi một câu hỏi về nó ở đây: F# quotations: variable may escape scopeMột hạn chế khác của các trích dẫn F #?
Bây giờ, tôi có thể đã gặp phải giới hạn khác khi chuyển đổi ví dụ xuất hiện trong http://www.cs.rice.edu/~taha/publications/journal/dspg04a.pdf từ MetaOcaml đến F #.
Lần này tôi đã đoạn MetaOcaml này:
let rec peval2 p env fenv=
match p with
Program ([],e) -> eval2 e env fenv
| Program (Declaration (s1,s2,e1)::tl,e) ->
.<let rec f x = .~(eval2 e1 (ext env s2 .<x>.)
(ext fenv s1 .<f>.))
in .~(peval2 (Program(tl,e)) env (ext fenv s1 .<f>.))>.
và tôi chuyển đổi nó để
let rec peval2 p env fenv =
match p with
| Program ([], e) -> eval2 e env fenv
| Program (Declaration (s1, s2, e1) :: tl, e) ->
<@ let rec f x = %(eval2 e1 (ext env s2 <@ x @>)
(ext fenv s1 <@ f @>))
in %(peval2 (Program(tl, e)) env (ext fenv s1 <@ f @>)) @>
tôi nhận được lỗi thời gian biên dịch sau: This expression was expected to have type int -> Expr<int> but here has type Expr<'a>
với hai <@ f @>
.
Bằng trực giác, tôi nghĩ rằng lỗi này có ý nghĩa rất lớn. Nhưng có cách nào trong F # để mô tả những gì tôi muốn trong trường hợp này?
mẫu Mã số:
open Microsoft.FSharp.Quotations
type Exp =
| Int of int
| Var of string
| App of string * Exp
| Add of Exp * Exp
| Sub of Exp * Exp
| Mul of Exp * Exp
| Div of Exp * Exp
| Ifz of Exp * Exp * Exp
type Def = Declaration of string * string * Exp
type Prog = Program of Def list * Exp
exception Yikes
let env0 = fun x -> raise Yikes
let fenv0 = env0
let ext env x v = fun y -> if x = y then v else env y
let rec eval2 e env fenv =
match e with
| Int i -> <@ i @>
| Var s -> env s
| App (s, e2) -> <@ %(fenv s) %(eval2 e2 env fenv) @>
| Add (e1, e2) -> <@ %(eval2 e1 env fenv) + %(eval2 e2 env fenv) @>
| Sub (e1, e2) -> <@ %(eval2 e1 env fenv) - %(eval2 e2 env fenv) @>
| Mul (e1, e2) -> <@ %(eval2 e1 env fenv) * %(eval2 e2 env fenv) @>
| Div (e1, e2) -> <@ %(eval2 e1 env fenv)/%(eval2 e2 env fenv) @>
| Ifz (e1, e2, e3) -> <@ if %(eval2 e1 env fenv) = 0
then %(eval2 e2 env fenv)
else %(eval2 e3 env fenv) @>
let rec peval2 p env fenv =
match p with
| Program ([], e) -> eval2 e env fenv
| Program (Declaration (s1, s2, e1) :: tl, e) ->
<@ let rec f x = %(eval2 e1 (ext env s2 <@ x @>)
(ext fenv s1 <@ f @>))
in %(peval2 (Program(tl, e)) env (ext fenv s1 <@ f @>)) @>
OK:/Tôi đã đăng một mẫu mã sản xuất lỗi mà tôi đang nói đến. Tuy nhiên, nếu tôi xóa một cặp các dòng từ eval2, tôi nhận được lỗi giống như câu hỏi khác: / –