From 73c96b0e0a2480becab920deecd04f7ec168e7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikuro=E3=81=95=E3=81=84=E3=81=AA?= Date: Wed, 17 Apr 2024 12:51:05 +0900 Subject: [PATCH] feat: Impl Eq and Ord for Array (#174) --- src/array.ts | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/array.ts b/src/array.ts index 91e5ae71..d285eb7f 100644 --- a/src/array.ts +++ b/src/array.ts @@ -1,4 +1,6 @@ import type { Get1, Hkt1 } from "./hkt.ts"; +import { andThen, map, type Option, some } from "./option.ts"; +import { and, type Ordering } from "./ordering.ts"; import { type Decoder, decU32Be, @@ -7,12 +9,47 @@ import { pureDecoder, } from "./serial.ts"; import { type Applicative, liftA2 } from "./type-class/applicative.ts"; +import { type Eq, fromEquality } from "./type-class/eq.ts"; import { type Foldable } from "./type-class/foldable.ts"; import type { Functor } from "./type-class/functor.ts"; import type { Monad } from "./type-class/monad.ts"; +import { fromCmp, type Ord } from "./type-class/ord.ts"; +import { + fromPartialEquality, + type PartialEq, +} from "./type-class/partial-eq.ts"; +import { fromPartialCmp, type PartialOrd } from "./type-class/partial-ord.ts"; import type { Reduce } from "./type-class/reduce.ts"; import type { Traversable } from "./type-class/traversable.ts"; +export const partialEquality = + (equality: PartialEq) => (l: readonly T[], r: readonly T[]) => + l.length === r.length && + l.every((left, i) => equality.eq(left, r[i])); +export const partialEq = fromPartialEquality(partialEquality); +export const partialCmp = + (order: PartialOrd) => + (l: readonly T[], r: readonly T[]): Option => + foldR(( + next: Option, + ): (acc: Option) => Option => + andThen((a: Ordering) => map(and(a))(next)) + )(some(Math.sign(l.length - r.length) as Ordering))( + l.map((left, i) => order.partialCmp(left, r[i])), + ); +export const partialOrd = fromPartialCmp(partialCmp); +export const equality = + (equality: Eq) => (l: readonly T[], r: readonly T[]) => + l.length === r.length && + l.every((left, i) => equality.eq(left, r[i])); +export const eq = fromEquality(equality); +export const cmp = + (order: Ord) => (l: readonly T[], r: readonly T[]): Ordering => + foldR(and)(Math.sign(l.length - r.length) as Ordering)( + l.map((left, i) => order.cmp(left, r[i])), + ); +export const ord = fromCmp(cmp); + export interface ArrayHkt extends Hkt1 { readonly type: readonly this["arg1"][]; }