That looks pretty good! One of the things I tried was to use the private type declaration. However, I failed to take the coercion into account, so I thought they couldn't actually be used as bigarrays.
I'd still like to avoid casting to bigarrays, but unless a miracle comes along, I think this is how I'll do it.
Thanks!

On Thu, Nov 16, 2017 at 4:49 PM, Yawar Amin <yawar.amin@gmail.com> wrote:
Hi Reed, this is maybe not exactly what you specified, but a `private` type abbreviation ( https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#s-private-types-abbrev ) should work. You'll have to cast your safe array type to a normal bigarray to get the indexing and other operations, e.g.:

(my_array : ro t :> (int, int8_unsigned_elt, c_layout) Array1.t).{idx}

Also, see http://camltastic.blogspot.ca/2008/05/phantom-types.html for a really cool way to mix phantom types and subtyping.

Cheers,

Yawar

On Thu, Nov 16, 2017 at 4:46 PM, Reed Wilson <cedilla@gmail.com> wrote:
A while ago, I made a module which basically extended bigarrays with a few more functions. However, I wanted to have a distinction between read-only and read-write values. The equivalence with bigarrays was irrelevant, so my interface just looked like this:

type ro
type rw
type 'a t
val read_only : 'a t -> ro t
val get : 'a t -> int -> int
val put : rw t -> int -> int -> unit
...

Basically, any function that wrote to the type would have to take a "rw t", but anything else would take " 'a t". From what I know about C, "ro" behaves like the "const" qualifier - not water-proof but it catches some of my common mistakes.

Now, however, I want to re-export the equivalence between 'a t and bigarrays (mostly for the .{} operator), but also have the read-only/read-write distinction. The problem is that if I write:
type 'a t = (int, int8_unsigned_elt, c_layout) Array1.t

then OCaml will see that "ro t" and "rw t" are the same and freely let me use "ro t" values in, for example, the "put" function above.

To summarize, is there a way to make two types internally represented by bigarrays, the first of which:
* can use the bigarray functions (specifically .{} )
* can use all of my new functions
and the second type
* can't use bigarray functions
* can only use a subset of my new functions

I don't want to have two different versions of each function that I have to keep track of.

Thanks,
Reed Wilson

--
ç




--
ç