首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F#报价的另一个限制?

F#报价的另一个限制?
EN

Stack Overflow用户
提问于 2011-06-21 05:51:24
回答 1查看 606关注 0票数 8

今天早些时候,我遇到了F#报价的限制,并在这里提出了一个问题:F# quotations: variable may escape scope

现在,在将http://www.cs.rice.edu/~taha/publications/journal/dspg04a.pdf中出现的示例从MetaOcaml转换为F#时,我可能遇到了另一个限制。

这一次我有了这个MetaOcaml代码片段:

代码语言:javascript
复制
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>.))>.

我把它转换成

代码语言:javascript
复制
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 @>)) @>

我得到以下编译时错误:带有两个<@ f @>This expression was expected to have type int -> Expr<int> but here has type Expr<'a>

凭直觉,我认为这个错误很有意义。但是在F#中有没有一种方法来描述我在这种情况下想要的东西呢?

代码示例:

代码语言:javascript
复制
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 @>)) @>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-21 06:49:57

我认为你遇到了与上一个问题相同的问题--当我从论文中复制必要的声明时,我得到了:

错误FS0446:变量'f‘绑定在引号中,但用作拼接表达式的一部分。这是不允许的,因为它可能会超出其范围。

这是有道理的--在拼接表达式中捕获引号中绑定的变量在F#中是不允许的,这肯定是在代码片段中完成的。

我不是很确定为什么你会得到一个不同的错误信息--如果你可以发布一个最小的完整样本,那么这个问题就可以得到回答,但你仍然会遇到这个变量捕获的限制。(这可能是在MetaOCaml中用得很多的东西)。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6418000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档