Belt.Map example does not appear to work


#1

This example, converted to ReasonML from https://github.com/BuckleScript/bucklescript/blob/master/jscomp/others/belt_Map.mli, does not appear to work when I put it into a .re file

module PairComparator =
  Belt.Id.MakeComparable(
    {
      type t = (int, int);
      let cmp = ((a0, a1), (b0, b1)) =>
        switch (Pervasives.compare(a0, b0)) {
        | 0 => Pervasives.compare(a1, b1)
        | c => c
        };
    }
  );

let myMap = Belt.Map.make(~id=(module PairComparator));

Giving this error:

  We've found a bug for you!
  /home/david/reasonlab/testor/src/demo.re 131:13-54
  
  129 │   );
  130 │ 
  131 │ let myMap = Belt.Map.make(~id=(module PairComparator));
  132 │ 
  
  
  This expression's type contains type variables that can't be generalized:
  Belt.Map.t(PairComparator.t, '_a, PairComparator.identity)

Any clues as to what I am doing wrong, or what has changed since that example was written?


#2

I believe you’re just missing the 2nd example line which type hints the annotation.

let myMap2 = Belt.Map.set(myMap, (1, 2), "myValue");


#3

I do not see where there is a type hint or any annotation on that line.

Here is the rest of the error message, which gave me something to read (but which [edit] is beginning to make a bit of sense)

  This happens when the type system senses there's a mutation/side-effect,
  in combination with a polymorphic value.
  Using or annotating that value usually solves it. More info:
  https://realworldocaml.org/v1/en/html/imperative-programming-1.html#side-effects-and-weak-polymorphism

#4

I meant that the full example seems to run fine in the playground

module PairComparator =
  Belt.Id.MakeComparable({
    type t = (int, int);
    let cmp = ((a0, a1), (b0, b1)) =>
      switch (Pervasives.compare(a0, b0)) {
      | 0 => Pervasives.compare(a1, b1)
      | c => c
      };
  });
let myMap = Belt.Map.make(~id=(module PairComparator));
let myMap2 = Belt.Map.set(myMap, (1, 2), "myValue");

Where the only difference is the last line!

(And sorry, I misspoke then, the usage of the Map makes the compiler infer the (int, int) where the comparator definition from before seems not to be enough!)


#5

You need to annotate the arguments to cmp, because of Pervasives.compare. It’s kinda tricky here


#6

Ah, that’s where the annotations go! Thanks.