This repository has been 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
/
ord.ts
93 lines (67 loc) · 2.64 KB
/
ord.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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// deno-lint-ignore-file no-explicit-any
import type { Ord } from "./type_classes.ts";
import type { Fn } from "./types.ts";
import { setoidStrict } from "./setoid.ts";
import { flow } from "./fns.ts";
/*******************************************************************************
* Internal
******************************************************************************/
// lte for primmimtives
const _lte = (a: any) => (b: any): boolean => a <= b;
const _equals = setoidStrict.equals;
/*******************************************************************************
* Models
******************************************************************************/
export type Ordering = -1 | 0 | 1;
export type Compare<A> = Fn<[A, A], Ordering>;
/*******************************************************************************
* Module Instances
******************************************************************************/
export const ordString: Ord<string> = {
equals: _equals,
lte: _lte,
};
export const ordNumber: Ord<number> = {
equals: _equals,
lte: _lte,
};
export const ordBoolean: Ord<boolean> = {
equals: _equals,
lte: _lte,
};
/*******************************************************************************
* Combinators
******************************************************************************/
export const compare = <A>(O: Ord<A>): Compare<A> =>
(a, b) => O.lte(a)(b) ? O.equals(a)(b) ? 0 : -1 : 1;
export const lt = <A>(O: Ord<A>) =>
(a: A) => (b: A): boolean => O.lte(a)(b) && !O.equals(a)(b);
export const gt = <A>(O: Ord<A>) => (a: A) => (b: A): boolean => !O.lte(a)(b);
export const lte = <A>(O: Ord<A>) => O.lte;
export const gte = <A>(O: Ord<A>) =>
(a: A) => (b: A): boolean => !O.lte(a)(b) || O.equals(a)(b);
export const eq = <A>(O: Ord<A>) => (a: A) => (b: A): boolean => O.equals(a)(b);
export const min = <A>(O: Ord<A>) => (a: A) => (b: A): A => O.lte(a)(b) ? a : b;
export const max = <A>(O: Ord<A>) => (a: A) => (b: A): A => O.lte(a)(b) ? b : a;
export const clamp = <A>(O: Ord<A>) =>
(low: A, high: A): ((a: A) => A) => flow(max(O)(low), min(O)(high));
export const between = <A>(O: Ord<A>) =>
(low: A, high: A) => {
const higher = lt(O)(low);
const lower = gt(O)(high);
return (a: A): boolean => lower(a) && higher(a);
};
/*******************************************************************************
* Combinator Getters
******************************************************************************/
export const getOrdUtilities = <A>(O: Ord<A>) => ({
lt: lt(O),
gt: gt(O),
lte: lte(O),
gte: gte(O),
eq: eq(O),
min: min(O),
max: max(O),
clamp: clamp(O),
compare: compare(O),
});