-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmonadio.js
70 lines (65 loc) · 1.6 KB
/
monadio.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
class MonadIODef {
constructor(effect) {
this.effect = effect;
}
then(fn) {
var self = this;
return new MonadIODef(function () {
return fn(self.effect());
});
}
flatMap(fn) {
return this.then((result)=>fn(result).effect());
}
of(ref) {
var m = new MonadIODef(()=>ref);
return m;
}
ap(fnM) {
return fnM.chain(f => this.map(f));
}
subscribe(fn, asynchronized) {
if (asynchronized) {
return Promise.resolve(0).then(this.effect).then(fn);
}
fn(this.effect())
return fn;
}
}
MonadIODef.prototype.just = MonadIODef.prototype.of
MonadIODef.prototype.chain = MonadIODef.prototype.flatMap
MonadIODef.prototype.bind = MonadIODef.prototype.then
MonadIODef.prototype.map = MonadIODef.prototype.then
var MonadIO = new MonadIODef({});
MonadIO.fromPromise = function (p) {
var m = new MonadIODef(function () {
return MonadIO.doM(function *() {
return yield p;
});
});
return m;
};
MonadIO.promiseof = function (ref) {
return Promise.resolve(ref);
};
MonadIO.wrapGenerator = function (genDef) {
var gen = genDef();
function step(value) {
var result = gen.next(value);
if (result.done) {
return result.value;
}
if (result.value instanceof MonadIODef) {
return result.value.subscribe((x)=>x, true).then(step);
}
return result.value.then(step);
}
return step;
};
MonadIO.generatorToPromise = function (genDef) {
return Promise.resolve().then(MonadIO.wrapGenerator(genDef));
}
MonadIO.doM = function (genDef) {
return MonadIO.wrapGenerator(genDef)();
};
module.exports = MonadIO;