Let's say I want to index all the elements of the set and store this indexing in a map. A working solution is to extend the Set module and create an inner functor:
module Make(M : Set.S) = struct
include M
module MakeIndexer(MM : Map.S with type key = elt) = struct
let index_set set =
let aux el (ix, acc) =
(ix + 1, MM.add el ix acc)
in
M.fold aux set (0, MM.empty) |> snd
end
end
Now, the use of the inner functor is a little cumbersome, I'd like to use an implementation using first class module. So far I got the following:
module Make(M : Set.S) = struct
include M
let index_map (module MM : Map.S with type key = elt) set =
let aux el (ix, acc) =
(ix + 1, MM.add el ix acc)
in
M.fold aux set (0, MM.empty) |> snd
end
I obtain the following error message
Characters 156-191:
M.fold aux set (0, MM.empty) |> snd
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type int MM.t
but an expression was expected of type int MM.t
The type constructor MM.t would escape its scope
I understand that I'm using syntatic sugar and that the module is locally bound in the function, but is there a way to write the function using first class module?
If I understand you correctly you want to make index-map algorithm polymorhic w.r.t to mapping structure. Indeed, you need only two things from the whole set of Map operations: inital value and an addition operator. So you can just pass them as a parameter to your function.
module Make(T : Set.OrderedType) = struct
module Set = Set.Make(T)
let index_map (set : Set.t) (map : 'm) add : 'm =
let aux el (ix, acc) =
(ix + 1, add el ix acc) in
Set.fold aux set (0, map) |> snd
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With