Search code examples
moduleocamlfunctor

In OCaml using Base, how do you construct a set with elements of type `int * int`?


In F#, I'd simply do:

> let x = Set.empty;;
val x : Set<'a> when 'a : comparison

> Set.add (2,3) x;;
val it : Set<int * int> = set [(2, 3)]

I understand that in OCaml, when using Base, I have to supply a module with comparison functions, e.g., if my element type was string

let x = Set.empty (module String);;
val x : (string, String.comparator_witness) Set.t = <abstr>

Set.add x "foo";;
- : (string, String.comparator_witness) Set.t = <abstr>

But I don't know how to construct a module that has comparison functions for the type int * int. How do I construct/obtain such a module?


Solution

  • There are examples in the documentation for Map showing exactly this.

    If you use their PPXs you can just do:

    module IntPair = struct
      module T = struct
        type t = int * int [@@deriving sexp_of, compare] 
      end
    
      include T
      include Comparable.Make(T)
    end
    

    otherwise the full implementation is:

    module IntPair = struct
      module T = struct
        type t = int * int
        let compare x y = Tuple2.compare Int.compare Int.compare
        let sexp_of_t = Tuple2.sexp_of_t Int.sexp_of_t Int.sexp_of_t
      end
    
      include T
      include Comparable.Make(T)
    end
    

    Then you can create an empty set using this module:

    let int_pair_set = Set.empty (module IntPair)