Indexing a set using a first-class module

Let's say I want to index all the elements in a set and store this indexing on a map. A working solution is to expand the Set module and create an internal 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 using the internal functor is a bit cumbersome; I would like to use an implementation using a first class module. So far I have received 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 get 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 use syntactic sugar and that the module is locally connected in the function, but is there a way to write this function using the first class module?

+4
source share
2 answers

Updated version

, polymorhic w.r.t . , Map: inital value . .

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
0

, .

.

, . , O (log n), , , , O (1) - .

, : .

-1

All Articles