How to extend the function Map.Make

I can write my own extension for the List OCaml module by specifying the lib.ml file and including the List module:

 module List = struct include List (* remove lx 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 the Map.Make functor, I tried something like the following in lib.ml :

 module Make (Ord : Map.OrderedType with type key = Ord.t) = struct include Map.Make(Ord) let aaa = 1 end 

However, compilation gives the error Error: The signature constrained by 'with' has no component named key .

Does anyone know how to do this?

+4
source share
2 answers

Why do you want to limit the argument signature of your functor? Here you do not need with type :

 module Make (Ord : Map.OrderedType) = struct include Map.Make(Ord) let aaa = 1 end 

gives a functor Make , which, when implementing Map.OrderedType returns a module with all Map.S functions, a key type equal to Ord.t , and an aaa value of type int .

If you want to force the result of your functor to adhere to a specific signature, you really need to add type constraints, for example.

 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 is one difference between Make and MakeAbstract . The former is of type t , equal to MapMake(Ord).t , and the latter is of the abstract type t

+2
source

The right way to do this is to follow the Map.mli structure with the S module, followed by the Make module.

myMap.mli

 module type S = sig include Map.S val keys: 'at -> key list end module Make (Ord: Map.OrderedType): S with type key = Ord.t 

You were right about the c restrictions, but you put it in the wrong position.

Then in myMap.ml :

 module type S = sig include Map.S val keys: 'at -> 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 this helps!

+1
source

Source: https://habr.com/ru/post/1499689/


All Articles