/
Identity.ts
135 lines (120 loc) · 3.24 KB
/
Identity.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
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
import { Monad1, MonadS1 } from '../Monad'
declare module '../HKT' {
interface URItoHKT<A> {
Identity: Identity<A>
}
}
const URI = 'Identity'
type URI = typeof URI
export const IDENTITY_URI = URI
export type IdentityURI = URI
/**
* A simple wrapper around a value which provides no special behavior.
*
* Identity is valuable in cases where some function expects an instance of Functor, Monad, or
* otherwise, but the data to pass needs no special behavior (as may be provided by something like
* Maybe).
*
* @category Identity
*/
export class Identity<A> implements Monad1<URI, A> {
/** @param value A value of any type to wrap in Identity */
private constructor(readonly value: A) {}
/**
* Create a new Identity object.
*
* @param a Any value to wrap with Identity.
*/
static of<A>(a: A): Identity<A> {
return new Identity(a)
}
/**
* A common alias of [[of]]
*
* @param a Any value to wrap with Identity
*/
static pure<A>(a: A): Identity<A> {
return new Identity(a)
}
toString(): String {
return `Identity ${String(this.value)}`
}
/**
* Apply a function to the value wrapped by Identity.
*
* @param f A unary function.
*/
map<B>(f: (a: A) => B): Identity<B> {
return identity.of(f(this.value))
}
/**
* Apply a function wrapped in Identity to the value wrapped by this Identity.
*
* @param fab An Identity wrapping a unary function.
*/
ap<B>(fab: Identity<(a: A) => B>): Identity<B> {
return identity.of(fab.value(this.value))
}
/**
* A monadic bind. Apply a function which returns an Identity without adding additional structure.
*
* @param fa A function which returns an Identity.
*/
chain<B>(fa: (a: A) => Identity<B>): Identity<B> {
return fa(this.value)
}
}
/**
* The set of static functions which can be applied with Identity
*
* @category Identity
*/
export const identity: MonadS1<URI> = {
/**
* Apply a function to the value within an Identity.
*
* @category Identity
* @param f A unary function.
* @param fa An Identity containing the value to which the function will be applied.
*/
map: <A, B>(f: (a: A) => B, fa: Identity<A>): Identity<B> => {
return fa.map(f)
},
/**
* Apply a function wrapped by Identity to the value within another Identity.
*
* @category Identity
* @param fab A unary function wrapped by Identity.
* @param fa An identity containing the value to which the function will be applied.
*/
ap: <A, B>(fab: Identity<(a: A) => B>, fa: Identity<A>): Identity<B> => {
return fa.ap(fab)
},
/**
* Create a new Identity object.
*
* @category Identity
* @param a Any value to wrap with Identity.
*/
of: <A>(a: A): Identity<A> => {
return Identity.of(a)
},
/**
* A common alias of [[of]]
*
* @category Identity
*/
pure: <A>(a: A): Identity<A> => {
return Identity.of(a)
},
/**
* Apply a function which returns Identity without adding structure.
*
* @category Identity
* @param fa A unary function which returns an Identity
* @param ma An identity containing the value to which the function will be applied.
*/
chain: <A, B>(fa: (a: A) => Identity<B>, ma: Identity<A>): Identity<B> => {
return ma.chain(fa)
}
}