UNPKG

2.05 kBJavaScriptView Raw
1var interfaces = {
2 semigroup: ['concat'],
3 monoid: ['concat', 'empty'],
4 functor: ['map'],
5 apply: ['map', 'ap'],
6 applicative: ['map', 'ap', 'of'],
7 chain: ['map', 'ap', 'chain'],
8 monad: ['map', 'ap', 'chain', 'of'],
9 extend: ['extend']
10};
11
12function correctInterface(type) {
13 return function(obj) {
14 return interfaces[type].every(function(method) {
15 return obj[method] && typeof obj[method] === 'function';
16 });
17 };
18}
19
20function identity(x) { return x; }
21
22module.exports = {
23 semigroup: {
24 iface: correctInterface('semigroup'),
25 associative: function(a, b, c) {
26 return a.concat(b).concat(c).equals(a.concat(b.concat(c)));
27 }
28 },
29
30 functor: {
31 iface: correctInterface('functor'),
32 id: function(obj) {
33 return obj.equals(obj.map(identity));
34 },
35 compose: function(obj, f, g) {
36 return obj.map(function(x) { return f(g(x)); }).equals(
37 obj.map(g).map(f)
38 );
39 }
40 },
41
42 apply: {
43 iface: correctInterface('apply'),
44 compose: function(a, u, v) {
45 return a.ap(u.ap(v)).equals(
46 a.map(function(f) {
47 return function(g) {
48 return function(x) {
49 return f(g(x));
50 };
51 };
52 }).ap(u).ap(v)
53 );
54 }
55 },
56
57 applicative: {
58 iface: correctInterface('applicative'),
59 id: function(obj, obj2) {
60 return obj.of(identity).ap(obj2).equals(obj2);
61 },
62 homomorphic: function(obj, f, x) {
63 return obj.of(f).ap(obj.of(x)).equals(obj.of(f(x)));
64 },
65 interchange: function(obj1, obj2, x) {
66 return obj2.ap(obj1.of(x)).equals(
67 obj1.of(function(f) { return f(x); }).ap(obj2)
68 );
69 }
70 },
71
72 chain: {
73 iface: correctInterface('chain'),
74 associative: function(obj, f, g) {
75 return obj.chain(f).chain(g).equals(
76 obj.chain(function(x) { return f(x).chain(g); })
77 );
78 }
79 },
80
81 monad: {
82 iface: correctInterface('monad')
83 },
84
85 extend: {
86 iface: correctInterface('extend')
87 }
88};