-
Notifications
You must be signed in to change notification settings - Fork 2
/
Maybe.js
123 lines (96 loc) · 3.13 KB
/
Maybe.js
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
import { factorizeSumType } from "./factories.js";
import { $$value } from "./Symbols.js";
/**
* ## Maybe
*
* The `Maybe` is the most common sum type; it represents the possibility of a value being `null` or `undefined`.
*
* The `Maybe` type implements the following algebras:
* - [x] Alternative
* - [x] Comonad
* - [x] Monad
*
* ### Example
*
* ```js
* import Maybe from "https://deno.land/x/functional@v1.3.0/library/Maybe.js";
*
* const containerA = Maybe.Just(42).map(x => x + 2);
* const containerB = Maybe.Nothing.map(x => x + 2);
*
* assert(Maybe.Just.is(containerA));
* assert(containerA.extract() === 44);
* assert(Maybe.Nothing.is(containerB));
* ```
*/
export const Maybe = factorizeSumType(
"Maybe",
{
Nothing: [],
Just: [ $$value ]
}
);
Maybe.fromNullable = value => !(typeof value !== "undefined") || !value && typeof value === "object"
? Maybe.nothing()
: Maybe.just(value);
Maybe.just = value => Maybe.Just(value);
Maybe.nothing = () => Maybe.Nothing;
Maybe.of = Maybe.prototype.of = Maybe.prototype["fantasy-land/of"] = value => Maybe.Just(value);
Maybe.prototype.alt = Maybe.prototype["fantasy-land/alt"] = function (container) {
return this.fold({
Nothing: _ => container,
Just: _ => this
});
};
Maybe.prototype.ap = Maybe.prototype["fantasy-land/ap"] = function (container) {
if (Maybe.Nothing.is(this)) return this;
return Maybe.Just.is(container) ? Maybe.of(container[$$value](this[$$value])) : container;
};
Maybe.prototype.chain = Maybe.prototype["fantasy-land/chain"] = function (unaryFunction) {
return this.fold({
Nothing: _ => Maybe.Nothing,
Just: value => unaryFunction(value)
});
};
Maybe.prototype.extend = Maybe.prototype["fantasy-land/extend"] = function (unaryFunction) {
return this.fold({
Nothing: _ => Maybe.Nothing,
Just: _ => Maybe.of(unaryFunction(this))
});
};
Maybe.prototype.extract = Maybe.prototype["fantasy-land/extract"] = function () {
return this.fold({
Nothing: _ => Maybe.Nothing,
Just: value => value
});
};
Maybe.prototype.filter = Maybe.prototype["fantasy-land/filter"] = function (predicate) {
return this.fold({
Nothing: _ => this,
Just: value => predicate(value) ? this : Maybe.Nothing
});
};
Maybe.prototype.map = Maybe.prototype["fantasy-land/map"] = function (unaryFunction) {
return this.fold({
Nothing: _ => this,
Just: value => Maybe.of(unaryFunction(value))
});
};
Maybe.prototype.reduce = Maybe.prototype["fantasy-land/reduce"] = function (binaryFunction, accumulator) {
return this.fold({
Nothing: _ => accumulator,
Just: value => binaryFunction(accumulator, value)
});
};
Maybe.prototype.sequence = function (TypeRepresentation) {
return this.traverse(TypeRepresentation, x => x);
};
Maybe.prototype.traverse = Maybe.prototype["fantasy-land/traverse"] = function (TypeRepresentation, unaryFunction) {
return this.fold({
Nothing: _ => TypeRepresentation.of(Maybe.Nothing),
Just: value =>
unaryFunction(value).map(x => Maybe.Just(x))
});
};
Maybe.zero = Maybe.prototype.zero = Maybe.prototype["fantasy-land/zero"] = () => Maybe.Nothing;
export default Maybe;