OCaml:仅从函数标识符返回函数

发布于 2024-10-21 12:28:24 字数 714 浏览 3 评论 0原文

我正在编写一个程序,它解析用某种编写的语言编写的脚本,并使用该脚本进行一些计算。该语言有一个特殊的构造,用于调用 'a ->; 类型的外部 OCaml 函数。布尔。因此,在我们可能拥有的语言中间

blah blah function (foo 45) blah blah

,我希望解析器使用构造函数,例如

OCamlFunction of ('a -> bool) * 'a

将该位解析为值,

OCamlFunction (foo,45)

其中“foo”是用户必须在单独的 .ml 中提供的函数文件并且解析器事先不知道;仅定义“foo”的 OCaml 文件的名称在运行时传递给解析器。因此,我需要定义一个 string->('a->bool) 类型的函数,它接受某个函数的名称并返回该函数。

我的问题是:

(1)我假设代码的动态加载应该使用 DynLink.loadfile。这是要走的路吗?

(2) 如何根据函数“foo”的标识符来访问该函数? (这会引导我到 camlp5 吗?)

I am writing a program which parses scripts written in some made-up language and does some computations using that script. This language has a particular construct which is used to call external OCaml functions of the type 'a -> bool. So, in the middle of the language we may have

blah blah function (foo 45) blah blah

and I'd like the parser to use a constructor such as

OCamlFunction of ('a -> bool) * 'a

to parse that bit as the value

OCamlFunction (foo,45)

where 'foo' is a function that the user will have to provide in a separate .ml file and which the parser doesn't know beforehand; only the name of the OCaml file where "foo" is defined is passed to the parser at runtime. So, I need to define a function of type string->('a->bool) which takes the name of some function and returns that function.

My questions are:

(1) I'm assuming that the dynamic loading of code should use DynLink.loadfile. Is this the way to go?

(2) How do I get access to the function "foo" from the knowledge of its identifier? (Will this lead me to camlp5?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稀香 2024-10-28 12:28:24

您不能直接按名称加载函数,因为 OCaml 没有这种支持,并且 loadfile 函数仅运行代码,它不提供对名称的访问。

您需要在主程序中支持加载代码使用的某种函数注册 API。因此,加载的代码将执行类似的操作,

ParserEngine.register_function "foo" foo_impl

您可以使用 Camlp{4,5} 来自动生成此样板代码,或者您可以进行 register_functions 调用,该调用采用关联列表来最小化它。

然后,register_functions 会将函数存储在某种内部结构中,例如哈希表或可变关联列表,以供解析器代码访问。

You cannot, directly, load a function by name, as OCaml does not have that kind of support and the loadfile function just runs the code, it does not provide access to names.

You need to support some kind of function registration API in your main program that is used by the loaded code. So the loaded code would do something like

ParserEngine.register_function "foo" foo_impl

You could use Camlp{4,5} to automate this boilerplate code generation, or you could have a register_functions call that takes an association list to minimize it.

register_functions would then store the functions in some internal structure like a hash table or mutable association list, ready for your parser code to access.

洋洋洒洒 2024-10-28 12:28:24

另一种解决方案是将整个脚本放在引号中,并将每个 ocaml 值放在反引号中。例如,这可以使用 Camlp4 来完成,但会产生轻微的语法成本(代码周围的 << >>$ OCaml 值周围的 $)。然后,脚本的解析将在编译时运行,因此 OCaml 类型器本身可以检查您引用的 OCaml 值是否定义良好。此外,您还可以获得更精细的类型控制。

Another solution would be to place the whole script in a quotation, and put each ocaml value inside in an antiquotation. This can be done with Camlp4 for example, but has a slight syntactic cost (<< >> around your code, $ $ around OCaml values). The parsing of the script would then run at compile-time, so the OCaml typer itself could check that the OCaml values you refer too are well defined. In addition, you get finer type control.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文