This repository was archived by the owner on May 3, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsetoid.ts
54 lines (42 loc) · 1.64 KB
/
setoid.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// deno-lint-ignore-file no-explicit-any
import type { Setoid } from "./type_classes.ts";
/*******************************************************************************
* Constructors
******************************************************************************/
export const fromEquals = <A>(
equals: (x: A) => (y: A) => boolean,
): Setoid<A> => ({
equals: (x) => (y) => x === y || equals(x)(y),
});
/*******************************************************************************
* Module Instances
******************************************************************************/
export const setoidStrict: Setoid<unknown> = {
equals: (a) => (b) => a === b,
};
export const setoidString: Setoid<string> = setoidStrict;
export const setoidNumber: Setoid<number> = setoidStrict;
export const setoidBoolean: Setoid<boolean> = setoidStrict;
export const setoidDate: Setoid<Date> = {
equals: (x) => (y) => x.valueOf() === y.valueOf(),
};
/*******************************************************************************
* Module Getters
******************************************************************************/
export const getStructSetoid = <O extends Readonly<Record<string, any>>>(
eqs: { [K in keyof O]: Setoid<O[K]> },
): Setoid<O> =>
fromEquals((x) =>
(y) => {
for (const k in eqs) {
if (!eqs[k].equals(x[k])(y[k])) {
return false;
}
}
return true;
}
);
export const getTupleSetoid = <T extends ReadonlyArray<Setoid<any>>>(
...eqs: T
): Setoid<{ [K in keyof T]: T[K] extends Setoid<infer A> ? A : never }> =>
fromEquals((x) => (y) => eqs.every((E, i) => E.equals(x[i])(y[i])));