I’m kind of stuck trying to figure out how can I use Base.Set in a recursive type definition.

So what I basically want ot achieve is something like this:

type value =

| Integer of int

| Float of float

| String of string

| Boolean of bool

| Variable of string

| Set of value Base.Set.t

But Base.Set constructor needs and element type and a comparator type ( `type ('elt, 'cmp) t`

). Element type is a no brainer, but I have no idea how I can define a comparator type. Not to mention I would need a comparator which can work on this recursive type.

I found an answer for making it work with Stdlib.Set by using recursive modules, but Base.Set doesn’t really have a similiar working functor like Stdlib.Set does(`Make`

).

You can use recursive module too, but this time with the comparator module. For instance,

```
module T: sig
type t = Set of (t, Cmp.comparator_witness) Set.t
end = T
and Cmp : Comparator.S with type t = T.t =
struct
type t = T.t
include Comparator.Make(struct
let compare x y = ...
let sexp_of_t x = ...
end)
end
let empty = T.Set (Set.empty (module Cmp));;
```

1 Like

Thanks a lot. Helped me to get this compileable example:

```
module rec MyType: sig
type t = Set of (t, MyComparator.comparator_witness) Base.Set.t
val compare: t -> t -> int
val sexp_of_t: t -> Base.Sexp.t
end = struct
type t = Set of (t, MyComparator.comparator_witness) Base.Set.t
let compare x y = -1
let sexp_of_t x = Base.Sexp.Atom "1"
end
and MyComparator : Base.Comparator.S with type t = MyType.t =
struct
type t = MyType.t
include Base.Comparator.Make(MyType)
end
let empty = MyType.Set (Base.Set.empty (module MyComparator));;
```

1 Like

This helps a lot. I happen to face the same problems (and I am new to `Base`

).

May I ask how to use `deriving sexp_of`

in this example? It seems I cannot simply put this after the definition of `type t`

.

Edit:

I still don’t figure out how to add `deriving sexp_of`

on this code. But I later found RWO gives an example on creating a new set without mentioning comparator_witness

```
type string_int_map =
int Map.M(String).t
[@@deriving sexp]
;;
type string_int_map = int Base.Map.M(Base.String).t
val string_int_map_of_sexp : Sexp.t -> string_int_map =
val sexp_of_string_int_map : string_int_map -> Sexp.t =
```

This idea works for my own code.