Skip to content

Instantly share code, notes, and snippets.

@ENAML
Last active December 11, 2020 11:52
Show Gist options
  • Save ENAML/76ae793976fa34aa9502c597e7c79f35 to your computer and use it in GitHub Desktop.
Save ENAML/76ae793976fa34aa9502c597e7c79f35 to your computer and use it in GitHub Desktop.
creating custom ReasonML comparable / hashable types that can be used with Bucklescript's Belt Hash/Map/Set types
/*
ocaml src: https://bucklescript.github.io/bucklescript/api/Belt.html
*/
/* base type */
type intTuple = (int, int);
/* hashable tuple */
module TupleHashable = Belt.Id.MakeHashable({
type t = intTuple;
let hash = ((a, b): t) => {
/* see: https://stackoverflow.com/a/13871379 */
let vA = a >= 0 ? 2 * a : -2 * a - 1;
let vB = b >= 0 ? 2 * b : -2 * b - 1;
let vC = (vA >= vB ? vA * vA + vA + vB : vA + vB * vB) / 2;
a < 0 && b < 0 || a >= 0 && b >= 0 ? vC : -vC - 1
};
let eq = ((x0, y0): t, (x1, y1): t) => {
x0 == x1 && y0 == y1
};
});
/* create hashset instance using hashable tuple */
let myHashSet = Belt.HashSet.make(
~id = (module TupleHashable),
~hintSize = 8
);
Belt.HashSet.add(myHashSet, (10, 10))
/* comparable tuple */
module TupleComparable = Belt.Id.MakeComparable({
type t = intTuple;
let cmp = ((a0, a1), (b0, b1)) => {
switch (Pervasives.compare(a0, b0)) {
| 0 => Pervasives.compare(a1, b1)
| c => c
}
};
});
/* map instance using hashable tuple */
let myMap = Belt.Set.make(~id=(module TupleComparable));
Belt.Set.add(myMap, (10, 10));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment