Note that there are some explanatory texts on larger screens.

plurals
  1. POHigher order types in OCaml (phantom types subtyping)
    primarykey
    data
    text
    <p>I'm using phantom types to emulate the state of a stack, as a wrapper module for ocaml-lua (Lua communicates with C/OCaml through a stack). Small code example:</p> <pre><code>type 's t type empty type 's table type top val newstate : unit -&gt; empty t (* stack empty *) val getglobal : empty t -&gt; top table t (* stack: -1 =&gt; table *) </code></pre> <p>Certain stack operations are possible on both tables and array-tables (no real arrays in Lua); some aren't. So if I have types</p> <pre><code>type 's table type 's array </code></pre> <p>I want a kind like table-or-array for functions that operate on both types, but still being able to forbid e.g. <code>rawgeti</code> (array operation) on tables. <code>objlen</code> is a stack operation that returns the "length" of the element at the top of the stack. This element can be both table or array-table. At the moment, the wrapper function is defined as follows:</p> <pre><code>val objlen : (top table) t -&gt; int </code></pre> <p>What I want is </p> <pre><code>val objlen : (top table-or-array) t -&gt; int </code></pre> <p>That is, <code>array</code> and <code>table</code> is subtypes of <code>table-or-array</code>.</p> <p>Any ideas?</p> <p>Regards Olle</p> <p><strong>Edit</strong></p> <p>After considerations, I came up with this:</p> <pre><code>module M : sig type ('s, 't) t (* New Lua state with empty stack *) val newstate : unit -&gt; (unit, unit) t (* Get table *) val getglobal : ('a) t -&gt; ([&lt; `table | `string | `number | `fn], 'a) t (* Get array index and put "anything" on top of stack *) val rawgeti : ([`table], 'a) t -&gt; ([&lt; `table | `string | `number | `fn], [`table] * 'a) t (* String on top of stack *) val tostring : ([`string], _) t -&gt; string (* Table or array-table on top of stack *) val objlen : ([`table], _) t -&gt; int val pop : ('a, 'b * 'c) t -&gt; ('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 </code></pre> <p>The stack at type level should now know neither more nor less than the stack itself. E.g. rawgeti will push on stack any type.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload