This repository has been archived by the owner on Jul 25, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathinterpreter-coproduct.js
104 lines (85 loc) · 2.3 KB
/
interpreter-coproduct.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
'use strict';
const daggy = require('daggy');
const {compose, identity} = require('fantasy-combinators');
const {Free} = require('./../fantasy-frees');
const Coproduct = require('fantasy-coproducts');
const IO = require('fantasy-io');
const FPrint = daggy.tagged('s', 'a');
const FRead = daggy.tagged('f');
const unit = daggy.tagged('x');
const Unit = () => unit('');
const Logger = daggy.taggedSum({
Error: ['x', 'a'],
Debug: ['x', 'a']
});
FPrint.prototype.map = function(f) {
return FPrint(this.s, f(this.a));
};
FRead.prototype.map = function(f) {
return FRead(compose(f)(this.f));
};
Logger.prototype.map = function(f) {
return this.cata({
Error: (a, b) => Logger.Error(a, f(b)),
Debug: (a, b) => Logger.Debug(a, f(b))
});
};
function fprint(s) {
return FPrint(s, Unit());
}
function fread() {
return FRead(identity);
}
function debug(x) {
return Logger.Debug(x, Unit());
}
function error(x) {
return Logger.Error(x, Unit());
}
function left(x) {
return Coproduct.left(x);
}
function right(x) {
return Coproduct.right(x);
}
function liftLeft(x) {
return Free.liftF(left(x));
}
function liftRight(x) {
return Free.liftF(right(x));
}
const readPrint = liftLeft(fprint("Hello, name?")).chain((_) => {
return liftRight(left(fread())).chain((name) => {
return liftRight(right(debug(name))).chain((_) => {
return liftLeft(fprint("Hi " + name + "!"));
});
});
});
function runIO(free) {
return free.resume().fold(
(x) => {
return x.coproduct(
(print) => {
console.log(print.s);
return runIO(print.a);
},
(y) => {
return y.coproduct(
(read) => {
return runIO(read.f("Timmy"))
},
(log) => {
log.cata({
Error: (x) => console.log('Error', x),
Debug: (x) => console.log('Debug', x)
});
return runIO(log.a);
}
);
}
);
},
IO.of
);
};
runIO(readPrint).unsafePerform();