Confused about using Belt.MutableMap

How to make an instance of Belt.MutableMap.t?

module M = {
  type t = int
}

let m = Belt.Id.comparable(~cmp=(m1: M.t, m2: M.t) => {
  m1 - m2
})

I got the type tip of m, but do not understand the meaning of it.
image

You need to use a first-class module to create a custom Belt.MutableMap.t. IMO, the first-class modules aren’t very well documented yet, but the basic idea is that they turn modules into values. Ordinarily, modules (module M = ...) and values (let x = ...) live on different “layers” of the language, and they can’t interact directly. With first-class modules, you can pass a module to a function like it was a value.

Here’s a working example. The easiest way is generally using Belt.Id.MakeComparable.

module M = {
  type t = int
  let cmp = (m1: t, m2: t) => m1 - m2
}

 // Create an new Id module
module M_Id = Belt.Id.MakeComparable(M)

 // use module() to turn M_Id into a first-class module
let map = Belt.MutableMap.make(~id=module(M_Id))
Belt.MutableMap.set(map, 1, "a")

You can use Belt.Id.comparable too, although it’s slightly different. It directly creates a first-class module for you. However, due to some advanced type-system quirks, ReScript requires that you “unpack” the FCM into a normal module anyway before you can use it.

module M = {
  type t = int
}

// Create an new Id module
module M_Id = unpack(Belt.Id.comparable(~cmp=(m1: M.t, m2: M.t) => m1 - m2))

// use module() to turn M_Id into a first-class module
let map = Belt.MutableMap.make(~id=module(M_Id))
Belt.MutableMap.set(map, 1, "a")
4 Likes

Thanks, it seems like that the first class module is not wtitten in documentation.