# Recursive modules and Base's Map.M()

**URL:** <https://discuss.ocaml.org/t/recursive-modules-and-bases-map-m/1521>\
**Category:** Learning\
**Tags:** base\
**Created:** [February 1, 2018, 8:50pm UTC](https://discuss.ocaml.org/t/recursive-modules-and-bases-map-m/1521 "2018-02-01T20:50:36Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jfeser](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jfeser/32/2093_2.png) [@jfeser](https://discuss.ocaml.org/u/jfeser)\
**Post date:** [February 1, 2018, 8:50pm UTC](https://discuss.ocaml.org/t/recursive-modules-and-bases-map-m/1521/1 "2018-02-01T20:50:36Z")

</div>

I’m trying to construct a variant type which contains a map that uses the variant type as a key.

```
open Base
module rec T : sig
  type t =
    | Int of int
    | Table of t Map.M(T).t
  [@@deriving compare, sexp]
  include Comparator.S with type t := t
end = struct
  type t =
    | Int of int
    | Table of t Map.M(T).t
  [@@deriving compare, sexp]
  include Comparator.Make(T)
end
include T

```

I’ve been using the Map module from Base, but I’m running into an error:

```
Error: Cannot safely evaluate the definition
   of the recursively-defined module T

```

I think this is because `Comparator.Make()` creates a `val comparator : (t, comparator_witness) comparator` so `T` isn’t a safe module. Any ideas on how to get around this?

---

<div class="post-metadata">

**Author:** ![schrodibear](https://avatars.discourse-cdn.com/v4/letter/s/958977/32.png) [@schrodibear](https://discuss.ocaml.org/u/schrodibear)\
**Post date:** [February 5, 2018, 3:04pm UTC](https://discuss.ocaml.org/t/recursive-modules-and-bases-map-m/1521/2 "2018-02-05T15:04:26Z")

</div>

I came up with a workaround, but I have little experience with Base, Core and TypeConv and so not sure this corresponds to the intended use of the libraries in such cases:

```ocaml
open Base

module type T0 = sig type t [@@deriving compare, sexp] end;;

module rec T0 : sig
  type comparator_witness
  type t =
    | Int of int
    | Table of (T0.t, t, comparator_witness) Map.t
  [@@deriving compare, sexp]
  val comparator : unit -> (t, comparator_witness) Comparator.t
end = struct
  module U = struct include (T0 : T0 with type t = T0.t) include Comparator.Make (T0) end
  type t =
    | Int of int
    | Table of t Map.M (U).t
  [@@deriving compare, sexp]
  type comparator_witness = U.comparator_witness
  let comparator () = U.comparator
end;;

module T1 = struct include T0 let comparator = T0.comparator () end;;

module T = struct
  type t = T1.t =
    | Int of int
    | Table of T1.t Map.M(T1).t
  include (T1 : module type of T1 with type t := t)
end;;

T.compare (T.Int 0) (T.Table (Map.of_alist_exn (module T) [T.Int 0, T.Int 1]));;

T.sexp_of_t (T.Table (Map.of_alist_exn (module T) [T.Int 0, T.Int 1]));;

```
