-
Notifications
You must be signed in to change notification settings - Fork 94
/
Copy pathIdentity.js
97 lines (83 loc) · 2.39 KB
/
Identity.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
var toString = require('ramda/src/toString');
var util = require('./internal/util');
/**
* A data type that holds a value and exposes a monadic api.
*/
/**
* Constructs a new `Identity[a]` data type that holds a single
* value `a`.
* @param {*} a Value of any type
* @sig a -> Identity[a]
*/
function Identity(x) {
if (!(this instanceof Identity)) {
return new Identity(x);
}
this.value = x;
}
Identity.prototype['@@type'] = 'ramda-fantasy/Identity';
/**
* Applicative specification. Creates a new `Identity[a]` holding the value `a`.
* @param {*} a Value of any type
* @returns Identity[a]
* @sig a -> Identity[a]
*/
Identity.of = function(x) {
return new Identity(x);
};
Identity.prototype.of = Identity.of;
/**
* Functor specification. Creates a new `Identity[a]` mapping function `f` onto
* `a` returning any value b.
* @param {Function} f Maps `a` to any value `b`
* @returns Identity[b]
* @sig @Identity[a] => (a -> b) -> Identity[b]
*/
Identity.prototype.map = function(f) {
return new Identity(f(this.value));
};
/**
* Apply specification. Applies the function inside the `Identity[a]`
* type to another applicative type.
* @param {Applicative[a]} app Applicative that will apply its function
* @returns Applicative[b]
* @sig (Identity[a -> b], f: Applicative[_]) => f[a] -> f[b]
*/
Identity.prototype.ap = function(app) {
return app.map(this.value);
};
/**
* Chain specification. Transforms the value of the `Identity[a]`
* type using an unary function to monads. The `Identity[a]` type
* should contain a function, otherwise an error is thrown.
*
* @param {Function} fn Transforms `a` into a `Monad[b]`
* @returns Monad[b]
* @sig (Identity[a], m: Monad[_]) => (a -> m[b]) -> m[b]
*/
Identity.prototype.chain = function(fn) {
return fn(this.value);
};
// chainRec
Identity.chainRec = Identity.prototype.chainRec = function(f, i) {
var state = util.chainRecNext(i);
while (state.isNext) {
state = f(util.chainRecNext, util.chainRecDone, state.value).get();
}
return Identity(state.value);
};
/**
* Returns the value of `Identity[a]`
*
* @returns a
* @sig (Identity[a]) => a
*/
Identity.prototype.get = function() {
return this.value;
};
// equality method to enable testing
Identity.prototype.equals = util.getEquals(Identity);
Identity.prototype.toString = function() {
return 'Identity(' + toString(this.value) + ')';
};
module.exports = Identity;