Last active
December 11, 2020 11:52
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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