今天早些时候我遇到了F#报价的限制,并在这里问了一个问题:F#报价:变量可能会逃避范围
现在,在将MetaOcaml中出现的http://www.cs.rice.edu/~taha/publications/journal/dspg04a.pdf中的示例转换为F#时,我可能遇到了另一个限制.
这次我有这个MetaOcaml片段:
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>.))>.
Run Code Online (Sandbox Code Playgroud)
我把它转换成了
let rec peval2 p env fenv =
match p with
| Program ([], e) -> eval2 e env fenv
| Program (Declaration (s1, s2, e1) :: tl, e) -> …Run Code Online (Sandbox Code Playgroud) 我刚刚安装了BER MetaOCaml,其中包括:
$ opam update
$ opam switch 4.02.1+BER
$ eval `opam config env`
Run Code Online (Sandbox Code Playgroud)
而且我无法在tuareg toplevel中运行MetaOCaml代码或只是ocaml toplevel.以下代码:
let a = .<1+2>.;;
Run Code Online (Sandbox Code Playgroud)
结果是
Error: Reference to undefined global `Trx'
Run Code Online (Sandbox Code Playgroud)
我试过#load "trx.cma"但它找不到文件.
答案编辑:
metaocaml是正确的可执行文件.
添加后:
`(defun tuareg-run-metaocaml ()
"Run an OCaml toplevel process. I/O via buffer `*ocaml-toplevel*'."
(interactive)
(tuareg-run-process-if-needed
"/usr/bin/opam config exec -- metaocaml")
(display-buffer tuareg-interactive-buffer-name))
(add-hook 'tuareg-mode-hook
' (lambda ()
(define-key tuareg-mode-map (kbd "C-c M-s")
'tuareg-run-metaocaml)))`
Run Code Online (Sandbox Code Playgroud)
对于我的.emacs,我现在可以运行MetaOCaml了C-c M-s.
在OCaml邮件列表上窃听人们之前,我想我可能会在这里发布我的问题.我刚发现这个美女(链接到Concoqtion网站).Concoqtion是MetaOCaml的扩展,它允许索引类型(可能还有更多).有了它,很容易创建列表,其中包括列表的长度:
type ('n:'(nat),'a) listl =
| Nil : ('(0),'a) listl
| Cons of let 'm:'(nat) in 'a * ('(m),'a) listl : ('(m+1),'a) listl
Run Code Online (Sandbox Code Playgroud)
这(m+1)是在类型级别完成的.井井有条.
但是,最后一个版本是2007年(OCaml 3.08).有谁知道为什么这个项目被取消,或者今天OCaml有类似的东西?
我有这段代码:
let rec h n z = if n = 0 then z
else <@ (fun x -> %(h (n - 1) <@ x + %z @>)) n @>
Run Code Online (Sandbox Code Playgroud)
从http://www.cs.rice.edu/~taha/publications/journal/dspg04a.pdf中的MetaOcaml示例转换而来
在本文中,解释了上面的例子将产生以下参数3和.<1>.(在MetaOcaml表示法中):
.<(fun x_1 -> (fun x_2 -> (fun x_3 -> x_3 + (x_2 + (x_1 + 1))) 1) 2) 3>.
Run Code Online (Sandbox Code Playgroud)
正如你所看到x的那样被替换为x_1,x_2等等,因为x否则只会引用x最里面的fun.
但是在F#中这是不允许的.我得到编译时错误:"变量'x'在引号中绑定,但用作拼接表达式的一部分.这是不允许的,因为它可能会逃避其范围." 所以问题是:如何改变它以便编译并具有与MetaOcaml输出相同的语义?
更新评论:我使用PowerPack来实际评估报价.但我不认为这与它有任何关系,因为错误是在编译时.到目前为止,QuotationEvaluation仍然有效.但是,我知道它可能不是最有效的实现.
更新Tomas的回答:
我真的不希望它x是全局的,或者是为了逃避范围.但我想要的是相当于
let rec h …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用MetaOCaml,所以我做了以下出色的代码:
#let a = .<1>.;;
val a : int code = .<1>.
# let b = !. a;;
Error: Unbound value !.
# let b = .!a;;
Error: Syntax error
Run Code Online (Sandbox Code Playgroud)
为什么不起作用?
另外,我也尝试过!.,.!因为我在网站上都看过这两个网站,但不知道哪一个是正确的网站。