OCaml 插件的任意类型接口
Interface of arbitrary types for OCaml Plugin
我正在使用 ocaml_plugin 编写能够在 运行 时间计算 OCaml 表达式的计算器。
这是我的插件界面。
open Ocaml_plugin.Std
module type S = sig
val f : unit -> float
end
let univ_constr : (module S) Ocaml_dynloader.Univ_constr.t =
Ocaml_dynloader.Univ_constr.create ()
我能够加载带有签名 unit -> float
的函数,例如,
let f () = 3.14159
let f () = 1.5 *. 1.5 *. 3.
并在主程序中调用f()对函数体中的表达式求值。但是,它只支持浮点类型。
想要支持int怎么办? Time.t?或者 Pervasive 中的任何任意 OCaml 类型?
let f () = List.length [1;2;3] (* int *)
let f () = Time.now () (* Time.t *)
let f () = "hello world!!!" (* string *)
为了在运行时进行评估,ocaml_plugin似乎是唯一的出路。但是,为了让loader/compiler知道动态加载的是什么,我不得不写一个接口。我应该如何更改接口文件以使其支持其他类型?
GADT(广义代数数据类型)拯救。
虽然GADT存在已久,但在OCaml中是一个比较新的话题。它对在 OCaml 中安全地编写泛型库有很大帮助。
module Value = struct
type 'a t
module Packed = struct
type 'a unpacked = 'a t
type t = T : 'a unpacked -> t
end
end
Value.Packed.t就是我们想要的打包数据类型。理论上任何数据类型 'a
都可以打包。
我正在使用 ocaml_plugin 编写能够在 运行 时间计算 OCaml 表达式的计算器。
这是我的插件界面。
open Ocaml_plugin.Std
module type S = sig
val f : unit -> float
end
let univ_constr : (module S) Ocaml_dynloader.Univ_constr.t =
Ocaml_dynloader.Univ_constr.create ()
我能够加载带有签名 unit -> float
的函数,例如,
let f () = 3.14159
let f () = 1.5 *. 1.5 *. 3.
并在主程序中调用f()对函数体中的表达式求值。但是,它只支持浮点类型。
想要支持int怎么办? Time.t?或者 Pervasive 中的任何任意 OCaml 类型?
let f () = List.length [1;2;3] (* int *)
let f () = Time.now () (* Time.t *)
let f () = "hello world!!!" (* string *)
为了在运行时进行评估,ocaml_plugin似乎是唯一的出路。但是,为了让loader/compiler知道动态加载的是什么,我不得不写一个接口。我应该如何更改接口文件以使其支持其他类型?
GADT(广义代数数据类型)拯救。
虽然GADT存在已久,但在OCaml中是一个比较新的话题。它对在 OCaml 中安全地编写泛型库有很大帮助。
module Value = struct
type 'a t
module Packed = struct
type 'a unpacked = 'a t
type t = T : 'a unpacked -> t
end
end
Value.Packed.t就是我们想要的打包数据类型。理论上任何数据类型 'a
都可以打包。