Reputation: 5540
I can write my own extension for List
module of OCaml, by defining a file lib.ml
and including List
module:
module List =
struct
include List
(* remove l x returns the list l without the first element x found or *)
(* returns l if no element is equal to x. *)
(* Elements are compared using ( = ). *)
let rec remove (l : 'a list) (x : 'a) : 'a list =
match l with
| [] -> []
| hd :: tl ->
if hd = x then
tl else
hd :: remove tl x
...
end
Then I can call Lib.List.remove ...
in other files.
Now I would like to write my own extension for Map.Make
functor, I tried something like follows in lib.ml
:
module Make (Ord : Map.OrderedType with type key = Ord.t) =
struct
include Map.Make(Ord)
let aaa = 1
end
However, the compilation gives an error Error: The signature constrained by 'with' has no component named key
.
Does anyone know how to do it?
Upvotes: 4
Views: 522
Reputation: 1739
The right way to do this is to follow the structure of Map.mli, with an S module followed by a Make module.
myMap.mli
module type S = sig
include Map.S
val keys: 'a t -> key list
end
module Make (Ord: Map.OrderedType): S with type key = Ord.t
you were right about the "with" constraints but you put it in the wrong position.
Then, in myMap.ml:
module type S = sig
include Map.S
val keys: 'a t -> key list
end
module Make = functor (Ord: Map.OrderedType) -> struct
module Map = Map.Make(Ord)
include Map
let keys m =
Map.fold (fun k _ acc -> k :: acc) m []
end
Hope that helps!
Upvotes: 1
Reputation: 10158
Why would you want to constraint the signature of the argument of your functor? You don't need any with type
here:
module Make (Ord : Map.OrderedType) =
struct
include Map.Make(Ord)
let aaa = 1
end
gives you a functor Make
that given an implementation of Map.OrderedType
returns a module with all the functions of Map.S
, a type key
equal to Ord.t
, and a value aaa
of type int
.
If you want to force the result of your functor to adhere to a certain signature, then you might indeed need to add type constraints, e.g.
module type MyMap = sig include Map.S val aaa: int end
module MakeAbstract (Ord : Map.OrderedType): MyMap with type key = Ord.t =
struct
include Map.Make(Ord)
let aaa = 1
end
There's one difference between Make
and MakeAbstract
. The former has a type t
equal to MapMake(Ord).t
while the latter has an abstract type t
Upvotes: 2