TypeScript で Haskell の comparing を実装してみた

https://hackage.haskell.org/package/base-4.19.0.0/docs/Data-Ord.html#v:comparing

たぶん既出(調べるの面倒で調べていない


実装:

function compareAsc<T>(x: T, y: T): number {
  return x < y ? -1 : y < x ? 1 : 0;
}
function compareDesc<T>(x: T, y: T): number {
  return -compareAsc(x, y);
}

function comparing<T, R>(
  f: (x: T) => R,
  compare: (x: R, y: R) => number = compareAsc,
): (x: T, y: T) => number {
  return (x, y) => compare(f(x), f(y));
}

function comparingWith<Obj, Key extends keyof Obj>(
  key: Key,
  compare: (x: Obj[Key], y: Obj[Key]) => number = compareAsc,
): (x: Obj, y: Obj) => number {
    return comparing((obj: Obj) => obj[key], compare);
}


使い方:

const arr = [
  {a: 1, b: 2},
  {a: -1, b: 4},
  {a: 0, b: 6},
  {a: 23, b: 8},
];

// obj.a でソート
console.log([...arr].sort(comparing(({a}) => a)));
// この場合はcomparingWithで楽に書ける
console.log([...arr].sort(comparingWith('a')));

// b で逆順
console.log([...arr].sort(comparingWith('b', compareDesc)));
// a + b でソート
console.log([...arr].sort(comparing(({ a, b }) => a + b)));


多分だけど既存のパッケージあります。 知ってたら教えてください。