Hello dear OCaml-ers,
(* categorical fonctor *)
module type Fonctor =
sig
type 'a t
val map : ('a -> 'b) -> 'a t -> 'b t
end
(* minimalist intuition about a polymorph data collection *)
module type DataCollection =
sig
include Fonctor
val size : 'a t -> int
type index
val member : index -> 'a t -> 'a
end
Compiles Ok.
(* Stdlib.List *)
module StdList
:
sig
include DataCollection
with type 'a t = 'a list
with type index = int
end
=
struct
type 'a t =
'a list
let map =
List.map
let size =
List.length
type index =
int
let member n l =
List.nth l n
end
(* Stdlib.Array *)
module StdArray
:
sig
include DataCollection
with type 'a t = 'a array
with type index = int
end
=
struct
type 'a t =
'a array
let map =
Array.map
let size =
Array.length
type index =
int
let member n a =
Array.get a n
end
Compiles Ok.
(* type PairIndex.index *)
module PairIndex
=
struct
type index = Fst | Snd
end
(* a pair of values *)
module Pair
:
sig
include DataCollection
with type 'a t = 'a * 'a
with type index = PairIndex.index
end
=
struct
type 'a t =
'a * 'a
let map f (x,y) =
(f x,f y)
let size t =
2
type index =
| Fst
| Snd
let member i (x,y) =
match i with
| Fst -> x
| Snd -> y
end
Does not compile because of a module-type with limitation.
Now a nested datatype from the paper Nested Datatypes by Richard Bird and Lambert Meertens 1998.
(* type 'a NestT.t *)
module NestT
=
struct
type 'a t =
| Nil
| Cons of 'a * ('a * 'a) t
end
(* one nested datatype from the paper "Nested Datatypes"
* by Richard Bird and Lambert Meertens 1998
*)
module Nest
:
sig
include DataCollection
with type 'a t = 'a NestT.t
with type index = int
end
=
struct
type 'a t =
| Nil
| Cons of 'a * ('a * 'a) t
(* same as Pair.map *)
let pair_map f (x,y) =
(f x,f y)
let rec map : 'a 'b . ('a -> 'b) -> 'a t -> 'b t =
fun f -> function
| Nil -> Nil
| Cons(h,t) -> Cons(f h,map (pair_map f) t)
let rec size : 'a . 'a t -> int = function
| Nil -> 0
| Cons(_,t) -> 1 + 2 * size t
type index =
int
let rec member : 'a . index -> 'a t -> 'a =
fun n -> function
| Nil -> failwith "Nest.member"
| Cons(h,t) ->
if n=0 then h else
let x,y = member (n/2) t in
if n mod 2 = 0 then x else y
end
Does not compile because of the same module-type with limitation.
Is there a workaround that i can’t see ?
If not then i fear not even 1ML could solve my case because i don’t do computation at the language-module-level.
Thanks