-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathidentity.ts
More file actions
163 lines (153 loc) · 3.48 KB
/
Copy pathidentity.ts
File metadata and controls
163 lines (153 loc) · 3.48 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**
* This file contains the Identity algebraic data type. Identity is one of the
* simplest data types in that it represents a type AS IS, allowing one to
* create algebraic structures for the inner type. This is most useful for
* constructing arrow optics.
*
* @module Identity
* @since 2.0.0
*/
import type { Kind, Out } from "./kind.ts";
import type { Applicable } from "./applicable.ts";
import type { Mappable } from "./mappable.ts";
import type { Flatmappable } from "./flatmappable.ts";
import type { Wrappable } from "./wrappable.ts";
/**
* Represents the Identity type constructor.
* @since 2.0.0
*/
export type Identity<A> = A;
/**
* Specifies Identity as a Higher Kinded Type, with covariant
* parameter A corresponding to the 0th index of any substitutions.
*
* @since 2.0.0
*/
export interface KindIdentity extends Kind {
readonly kind: Identity<Out<this, 0>>;
}
/**
* Wraps a value into an Identity type.
* This function allows any value to be lifted into the context of an Identity,
* making it possible to interact with other functions that operate on the Identity type.
*
* @example
* ```ts
* import { wrap } from "./identity.ts";
*
* // numberIdentity is Identity<number> with value 5
* const numberIdentity = wrap(5);
*
* // stringIdentity is Identity<string> with value "hello"
* const stringIdentity = wrap("hello");
* ```
*
* @param a - The value to wrap.
* @returns The wrapped value as an Identity.
* @since 2.0.0
*/
export function wrap<A>(a: A): Identity<A> {
return a;
}
/**
* Apply a function to the value in an Identity.
*
* @example
* ```ts
* import { map, wrap } from "./identity.ts";
* import { pipe } from "./fn.ts";
*
* const identity = wrap(5);
* const doubled = pipe(
* identity,
* map(n => n * 2)
* );
*
* console.log(doubled); // 10
* ```
*
* @since 2.0.0
*/
export function map<A, I>(fai: (a: A) => I): (ta: Identity<A>) => Identity<I> {
return fai;
}
/**
* Apply a function wrapped in an Identity to a value wrapped in an Identity.
*
* @example
* ```ts
* import { apply, wrap } from "./identity.ts";
* import { pipe } from "./fn.ts";
*
* const identityFn = wrap((n: number) => n * 2);
* const identityValue = wrap(5);
* const result = pipe(
* identityFn,
* apply(identityValue)
* );
*
* console.log(result); // 10
* ```
*
* @since 2.0.0
*/
export function apply<A>(
ua: Identity<A>,
): <I>(ufai: Identity<(a: A) => I>) => Identity<I> {
return (ufai) => ufai(ua);
}
/**
* Chain Identity computations together.
*
* @example
* ```ts
* import { flatmap, wrap } from "./identity.ts";
* import { pipe } from "./fn.ts";
*
* const identity = wrap(5);
* const chained = pipe(
* identity,
* flatmap(n => wrap(n * 2))
* );
*
* console.log(chained); // 10
* ```
*
* @since 2.0.0
*/
export function flatmap<A, I>(
fati: (a: A) => Identity<I>,
): (ta: Identity<A>) => Identity<I> {
return fati;
}
/**
* The canonical implementation of Applicable for Identity.
*
* @since 2.0.0
*/
export const ApplicableIdentity: Applicable<KindIdentity> = {
apply,
map,
wrap,
};
/**
* The canonical implementation of Mappable for Identity.
*
* @since 2.0.0
*/
export const MappableIdentity: Mappable<KindIdentity> = { map };
/**
* The canonical implementation of Flatmappable for Identity.
*
* @since 2.0.0
*/
export const FlatmappableIdentity: Flatmappable<KindIdentity> = {
apply,
map,
flatmap,
wrap,
};
/**
* @since 2.0.0
*/
export const WrappableIdentity: Wrappable<KindIdentity> = { wrap };