我正在使用虚拟类型来模拟堆栈的状态,作为ocaml-lua的包装模块(Lua通过堆栈与C/OCaml通信)。以下是一个小的代码示例:
type 's t
type empty
type 's table
type top
val newstate : unit -> empty t (* stack empty *)
val getglobal : empty t -> top table t (* stack: -1 => table *)
在Lua中,表和数组表(没有真正的数组)都可以进行某些堆栈操作,但有些操作是不可行的。因此,如果我有以下类型:
type 's table
type 's array
我希望有一种类似于表格或数组的函数类型,可以同时操作两种类型,但仍能禁止如rawgeti(数组操作)在表格上的使用。 objlen是一个堆栈操作,返回堆栈顶部元素的“长度”。该元素可以是表格或数组表格。目前,封装函数定义如下:
val objlen : (top table) t -> int
What I want is
val objlen : (top table-or-array) t -> int
那么,
array
和table
是table-or-array
的子类型。
有什么想法吗?
谢谢 Olle
编辑
经过考虑,我得出了以下结论:
module M : sig
type ('s, 't) t
(* New Lua state with empty stack *)
val newstate : unit -> (unit, unit) t
(* Get table *)
val getglobal : ('a) t -> ([< `table | `string | `number | `fn], 'a) t
(* Get array index and put "anything" on top of stack *)
val rawgeti : ([`table], 'a) t -> ([< `table | `string | `number | `fn], [`table] * 'a) t
(* String on top of stack *)
val tostring : ([`string], _) t -> string
(* Table or array-table on top of stack *)
val objlen : ([`table], _) t -> int
val pop : ('a, 'b * 'c) t -> ('b, 'c) t
end = struct
type top
type ('s, 't) t = string (* Should really be Lua_api.Lua.state *)
(* Dummy implementations *)
let newstate () = "state"
let gettable s = s
let getarray s = s
let rawgeti s = s
let tostring s = "Hello phantom world!"
let objlen s = 10
let pop s = s
end
在类型级别上的堆栈现在不应该比堆栈本身多也不应该比堆栈本身少。例如,rawgeti将在堆栈上推送任何类型。
type ('s, 't) t val objlen : (top, [< \
table | `array]) t -> int` 是什么意思? - lukstafi[< \
table | `array]与
[`table | `array]` 是相同的。 - lukstafi