I’m trying to write a function that returns the maximum value of an array given a comparator function. That’s one of those functions that returns -1 if the first parameter is less than the second, +1 if the first parameter is greater than the second, and 0 if they are the same. I can get it to work as shown below.
type nonEmptyArray<'t> = NonEmptyArray(array<'t>)
let make = xs =>
switch xs {
| [] => None
| xs => xs->NonEmptyArray->Some
}
// Does not require a default/initial value because array has
// at least 1 item. And will always return a meaningful result.
let maxBy = (NonEmptyArray(n), cmp) => n->Js.Array2.reduce((maximum, i) =>
if cmp(i, maximum) < 0 {
maximum
} else {
i
}
, n[0])
This is pretty good, but I don’t like that my cmp
function is not really documented anywhere. It’s just a function that takes two of something and returns an int. So I’m trying to reuse some well-defined comparer function type but can’t figure out how to do it. This doesn’t work…
// SYNTAX ERROR
type comparer<'t> = (~a:'t,~b:'t) => int
let bigger<'t> = (a,b,cmp:comparer<'t>) =>
if cmp(a,b)<0 {
b
}
else {
a
}
I figure for many of my types I’ll define comparator/id modules - still a big confused what these things are - so I can use them in sets and maps. But I can’t figure out how to re-use the compare function built into these things.
// SYNTAX ERROR
module IntComparable = Belt.Id.MakeComparable({
type t = int
let cmp = (a, b) => Pervasives.compare(a, b)
})
let compareTwoIntegers = (a, b) => IntComparable.cmp(a, b)