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
/
Copy pathmonoid.ts
80 lines (66 loc) · 2.3 KB
/
monoid.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
import type { Monoid, Semigroup } from "./type_classes.ts";
import { constant } from "./fns.ts";
import * as S from "./semigroup.ts";
/*******************************************************************************
* Module Instances
******************************************************************************/
export const monoidAll: Monoid<boolean> = {
concat: S.semigroupAll.concat,
empty: constant(true),
};
export const monoidAny: Monoid<boolean> = {
concat: S.semigroupAny.concat,
empty: constant(false),
};
export const monoidSum: Monoid<number> = {
concat: S.semigroupSum.concat,
empty: constant(0),
};
export const monoidProduct: Monoid<number> = {
concat: S.semigroupProduct.concat,
empty: constant(1),
};
export const monoidString: Monoid<string> = {
concat: S.semigroupString.concat,
empty: constant(""),
};
export const monoidVoid: Monoid<void> = {
concat: S.semigroupVoid.concat,
empty: constant(undefined),
};
/*******************************************************************************
* Module Getters
******************************************************************************/
export const getTupleMonoid = <T extends ReadonlyArray<Monoid<unknown>>>(
...monoids: T
): Monoid<{ [K in keyof T]: T[K] extends Semigroup<infer A> ? A : never }> => {
const zero = monoids.map((m) => m.empty());
const concat = S.getTupleSemigroup(...monoids).concat;
return (({
concat,
empty: () => zero,
}) as unknown) as Monoid<
{ [K in keyof T]: T[K] extends Semigroup<infer A> ? A : never }
>;
};
export const getDualMonoid = <A>(M: Monoid<A>): Monoid<A> => ({
concat: S.getDualSemigroup(M).concat,
empty: M.empty,
});
export const getStructMonoid = <O extends Record<string, () => unknown>>(
monoids: { [K in keyof O]: Monoid<O[K]> },
): Monoid<O> => {
const empty: Record<string, O[keyof O]> = {};
for (const key of Object.keys(monoids)) {
empty[key] = monoids[key].empty();
}
return {
concat: S.getStructSemigroup(monoids).concat,
empty: () => (empty as unknown) as O,
};
};
/*******************************************************************************
* Pipeables
******************************************************************************/
export const fold = <A>(M: Monoid<A>) =>
(as: ReadonlyArray<A>): A => S.fold(M)(M.empty())(as);