20

I need an OCaml map with keys of type int so I am using Map.Make to create one. However it seems that the standard modules 'only' provide modules like Big_int, Int32, Int64 and Nativeint which require conversions. So I have to do things like:

module IntMap = Map.Make(Int32) 
let a_map = IntMap.add (Int32.of_int 0) "zero" IntMap.empty ;;

... which I would rather avoid or define my own silly Int module do deal with simple int literals or values without requiring conversion functions:

module Int = struct                       
   type t = int                                              
   let compare x y = if x < y then -1 else if x > y then 1 else 0 end ;;  
module IntMap = Map.Make(Int) 
let a_map = IntMap.add 0 "zero" IntMap.empty ;;

Am I missing something obvious here?

Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331

4 Answers4

31

The simplest way to have an int map is to do the following:

module IntMap = Map.Make(struct type t = int let compare = compare end)
Thomas
  • 5,047
  • 19
  • 30
  • 1
    You would probably prefer to add a type annotation to the compare function for efficiency reasons: inline `module IntMap = Map.Make(struct type t = int let compare : int -> int -> int = compare end)` – Pierre Chambart Apr 14 '12 at 07:21
  • @PierreChambart Do you have a use-case where this makes a difference ? Both generated lambda codes looks similar to me. – Thomas Apr 14 '12 at 10:28
  • Effectively, I don't know why, but I can't get the compiler to specialise compare as compare_int in this case. – Pierre Chambart Apr 14 '12 at 11:39
  • In ocamlc version 3.11.2 the line: `module IntMap = Map.Make(struct type t = int let compare = compare end)` fails with "**Syntax error: ')' expected, the highlighted '(' might be unmatched**" at the toplevel (similar error message at the ocamlc -c invocation) – Marcus Junius Brutus Apr 17 '12 at 10:16
  • This error can happen in the toplevel in the tuareg mode (because of a bug in the tuareg mode), but should normally compile fine with 3.11.2 (but I haven't tested it). You can stil do: `module Int = struct type t = int let compare = compare end` and `module IntMap = Map.Make(Int)` – Thomas Apr 17 '12 at 16:38
7

I dont think you're missing anything, there's no standard module for this. I believe the BatInt module of OCaml Batteries Included does what you want.

(Edited to add: it's true, I myself use the method suggested by Thomas!)

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108
2

You can build IntMap with a one-liner. If you don't mind using third-party libraries, Jean-Christophe Filliâtre's Patricia tree library (Ptmap) is a little more efficient (and similarly Ptset for sets of OCaml integers).

Community
  • 1
  • 1
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
0

If you happen to use containers already (which I think is a bit more commonplace since previous answers were written), you can conveniently use the containers 'primitive' modules along with the CCMap module to achieve this, e.g.:

module ByInt = CCMap.Make(CCInt)

actionshrimp
  • 5,219
  • 3
  • 23
  • 26