From e5dbcfd4954b2471182d052a02f271f0600a8b75 Mon Sep 17 00:00:00 2001 From: "http://jayferd.us/" Date: Wed, 8 Jan 2014 16:48:54 -0800 Subject: [PATCH 1/6] reference Parsimmon in the implementations list --- implementations.md | 1 + 1 file changed, 1 insertion(+) diff --git a/implementations.md b/implementations.md index 218da32..0cb97f1 100644 --- a/implementations.md +++ b/implementations.md @@ -20,6 +20,7 @@ Here are a list of implementations that live in Fantasy Land: Promises that implements Semigroup, Monoid, Functor, Applicative, Chain and Monad * [Pirandello](https://github.com/quarterto/Pirandello) better streams, with a MonadPlus +* [Parsimmon](https://github.com/jayferd/parsimmon) implements parsers that are semigroups, applicative functors, and monads. Conforming implementations are encouraged to promote the Fantasy Land logo: From 9742cbafbca56d84c29ed0b20efe1181d5113946 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 19 Mar 2014 23:32:30 -0400 Subject: [PATCH 2/6] Added Bennu and Akh to implementations.md --- implementations.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/implementations.md b/implementations.md index 0cb97f1..70f40fb 100644 --- a/implementations.md +++ b/implementations.md @@ -21,7 +21,9 @@ Here are a list of implementations that live in Fantasy Land: Monad * [Pirandello](https://github.com/quarterto/Pirandello) better streams, with a MonadPlus * [Parsimmon](https://github.com/jayferd/parsimmon) implements parsers that are semigroups, applicative functors, and monads. - +* [Bennu](https://github.com/mattbierner/bennu/) parsec style parser combinators implement monad, monoid, functor, and applicative functor. +* [Akh](https://github.com/mattbierner/akh/) is a collection of monad transformers and common structures that implement Fantasy Land interfaces. + Conforming implementations are encouraged to promote the Fantasy Land logo: ![](logo.png) From b24e7c09d15a4f3d961fa157f00dd6cbc870f786 Mon Sep 17 00:00:00 2001 From: Hardy Jones Date: Thu, 20 Mar 2014 08:58:27 -0700 Subject: [PATCH 3/6] Add Apply We should support this, and also clean up the hierarchy a bit. Since currently chain doesn't have to be a functor, but we all know it is. Please give it a once over, might have messed up some of the conversion. --- README.md | 49 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 2fdeb8c..1d18e4b 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ structures: * Semigroup * Monoid * Functor +* Apply * Applicative * Chain * Monad @@ -93,37 +94,43 @@ method takes one argument: 2. `map` must return a value of the same Functor -### Applicative +### Apply -A value that implements the Applicative specification must also +A value that implements the Apply specification must also implement the Functor specification. -A value which satisfies the specification of a Applicative does not -need to implement: - -* Functor's `map`; derivable as `function(f) { return this.of(f).ap(this); })}` - -1. `a.of(function(a) { return a; }).ap(v)` is equivalent to `v` (identity) -2. `a.of(function(f) { return function(g) { return function(x) { return f(g(x))}; }; }).ap(u).ap(v).ap(w)` is equivalent to `u.ap(v.ap(w))` (composition) -3. `a.of(f).ap(a.of(x))` is equivalent to `a.of(f(x))` (homomorphism) -4. `u.ap(a.of(y))` is equivalent to `a.of(function(f) { return f(y); }).ap(u)` (interchange) +1. `a.map(function(f) { return function(g) { return function(x) { return f(g(x))}; }; }).ap(u).ap(v)` is equivalent to `a.ap(u.ap(v))` (composition) #### `ap` method -A value which has an Applicative must provide an `ap` method. The `ap` +A value which has an Apply must provide an `ap` method. The `ap` method takes one argument: a.ap(b) -1. `a` must be an Applicative of a function, +1. `a` must be an Apply of a function, 1. If `a` does not represent a function, the behaviour of `ap` is unspecified. -2. `b` must be an Applicative of any value +2. `b` must be an Apply of any value + +3. `ap` must apply the function in Apply `a` to the value in + Apply `b` -3. `ap` must apply the function in Applicative `a` to the value in - Applicative `b` +### Applicative + +A value that implements the Applicative specification must also +implement the Apply specification. + +A value which satisfies the specification of an Applicative does not +need to implement: + +* Functor's `map`; derivable as `function(f) { return this.of(f).ap(this); })}` + +1. `a.of(function(a) { return a; }).ap(v)` is equivalent to `v` (identity) +2. `a.of(f).ap(a.of(x))` is equivalent to `a.of(f(x))` (homomorphism) +3. `u.ap(a.of(y))` is equivalent to `a.of(function(f) { return f(y); }).ap(u)` (interchange) #### `of` method @@ -139,6 +146,14 @@ or its `constructor` object. The `of` method takes one argument: ### Chain +A value that implements the Chain specification must also +implement the Apply specification. + +A value which satisfies the specification of a Chain does not +need to implement: + +* Apply's `ap`; derivable as `m.chain(function(f) { return m.map(f); })` + 1. `m.chain(f).chain(g)` is equivalent to `m.chain(function(x) { return f(x).chain(g); })` (associativity) #### `chain` method @@ -164,7 +179,7 @@ the Applicative and Chain specifications. A value which satisfies the specification of a Monad does not need to implement: -* Applicative's `ap`; derivable as `function(m) { return this.chain(function(f) { return m.map(f); }); }` +* Apply's `ap`; derivable as `function(m) { return this.chain(function(f) { return m.map(f); }); }` * Functor's `map`; derivable as `function(f) { var m = this; return m.chain(function(a) { return m.of(f(a)); })}` 1. `m.of(a).chain(f)` is equivalent to `f(a)` (left identity) From 93d98e5335418ffb2e6ecf570a5b525148ff0e94 Mon Sep 17 00:00:00 2001 From: Oleg Grenrus Date: Sun, 13 Apr 2014 12:03:51 +0300 Subject: [PATCH 4/6] Update package.json, bump version to 0.1.0 --- package.json | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 1d5e7e8..35b4f0f 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,28 @@ { - "name": "fantasy-land", - "author": "Brian McKenna", - "version": "0.0.1", - "description": "Specification for interoperability of common algebraic structures in JavaScript", - "license": "XXX", - "homepage": "https://github.com/pufuwozu/fantasy-land", - "keywords": [ - "algebraic", - "monad", - "functor", - "monoid", - "semigroup" - ], - "issues": { - "url": "https://github.com/pufuwozu/fantasy-land/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/pufuwozu/fantasy-land.git" - }, - "files": ["id.js"] + "name": "fantasy-land", + "author": "Brian McKenna", + "version": "0.1.0", + "description": "Specification for interoperability of common algebraic structures in JavaScript", + "license": "XXX", + "homepage": "https://github.com/fantasyland/fantasy-land", + "keywords": [ + "algebraic", + "monad", + "applicative", + "functor", + "monoid", + "semigroup", + "chain", + "apply" + ], + "issues": { + "url": "https://github.com/fantasyland/fantasy-land/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/fantasyland/fantasy-land.git" + }, + "files": [ + "id.js" + ] } From a5cd0d5474d93e7109b21bcd06d7a6c7431694cf Mon Sep 17 00:00:00 2001 From: Oleg Grenrus Date: Sun, 13 Apr 2014 20:29:52 +0300 Subject: [PATCH 5/6] Add setoid at plgebra --- README.md | 21 +++++++++++++++++++++ id.js | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/README.md b/README.md index 1d18e4b..2b1c0cd 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This project specifies interoperability of common algebraic structures: +* Setoid * Semigroup * Monoid * Functor @@ -38,6 +39,26 @@ implemented and how they can be derived from new methods. ## Algebras +### Setoid + +1. `a.equals(a) === true` (reflexivity) +2. `a.equals(b) === b.equals(a)` (symmetry) +3. If `a.equals(b)` and `b.equals(c)`, then `a.equals(c)` (transitivity) + +#### `equals` method + +A value which has a Setoid must provide an `equals` method. The +`equals` method takes one argument: + + a.equals(b) + +1. `b` must be a value of the same Setoid + + 1. If `b` is not the same Setoid, behaviour of `equals` is + unspecified (returning `false` is recommended). + +2. `equals` must return a boolean (`true` or `false`). + ### Semigroup 1. `a.concat(b).concat(c)` is equivalent to `a.concat(b.concat(c))` (associativity) diff --git a/id.js b/id.js index faa7fdc..e8099cf 100644 --- a/id.js +++ b/id.js @@ -2,6 +2,11 @@ function Id(a) { this.value = a; } +// Setoid +Id.prototype.equals = function (b) { + return typeof this.value.equals === "function" ? this.value.equals(b.value) : this.value === b.value; +}; + // Semigroup (value must also be a Semigroup) Id.prototype.concat = function(b) { return new Id(this.value.concat(b.value)); From 294d1078231ca9cc7abd652ea7fb860b2b79cdde Mon Sep 17 00:00:00 2001 From: Oleg Grenrus Date: Tue, 15 Apr 2014 14:25:00 +0300 Subject: [PATCH 6/6] Add dependency graph --- README.md | 2 + figures/dependencies.mp | 67 ++++++++++++++++++ figures/dependencies.png | Bin 0 -> 3571 bytes figures/dependencies.svg | 147 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 216 insertions(+) create mode 100644 figures/dependencies.mp create mode 100644 figures/dependencies.png create mode 100644 figures/dependencies.svg diff --git a/README.md b/README.md index 1d18e4b..75bcaae 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ structures: * Chain * Monad +![](figures/dependencies.png) + ## General An algebra is a set of values, a set of operators that it is closed diff --git a/figures/dependencies.mp b/figures/dependencies.mp new file mode 100644 index 0000000..1b8709a --- /dev/null +++ b/figures/dependencies.mp @@ -0,0 +1,67 @@ +prologues := 3; +outputtemplate := "%j.svg"; +outputformat := "svg"; + +dimX=2.5cm; +dimY=-1.5cm; + +vardef clippath(expr p, a, b) = + save q, s, t, r; + + numeric s; + path q[]; + numeric t; + path r; + + q1 = bbox(a); + q2 = bbox(b); + + (whatever, t1) = q1 intersectiontimes p; + (whatever, t2) = q2 intersectiontimes (reverse p); + + subpath (t1, length(p) - t2) of p +enddef; + +def midpoint(expr p) = point 0.5 of p enddef; + +beginfig(1); +picture q[]; + +z1=(0dimX, 0dimY); +z2=(0dimX, 1dimY); + +z3=(1dimX, 0dimY); +z4=(1dimX, 1dimY); +z5=(2dimX, 1dimY); + +z6=(1dimX, 2dimY); +z7=(2dimX, 2dimY); + +% domain labels +q1 = thelabel("Semigroup", z1); +q2 = thelabel("Monoid", z2); + +q3 = thelabel("Functor", z3); + +q4 = thelabel("Apply", z4); +q5 = thelabel("Applicative", z5); + +q6 = thelabel("Chain", z6); +q7 = thelabel("Monad", z7); + +for i=1 upto 7: + draw q[i]; +endfor + +% arrows + +drawarrow clippath(z1..z2, q1, q2); % Semigroup -> Monoid + +drawarrow clippath(z3..z4, q3, q4); % Functor -> Apply +drawarrow clippath(z4..z5, q4, q5); % Apply -> Applicative +drawarrow clippath(z4..z6, q4, q6); % Apply -> Chain +drawarrow clippath(z5..z7, q5, q7); % Applicative -> Monad +drawarrow clippath(z6..z7, q6, q7); % Chain -> Monad + +endfig; +end diff --git a/figures/dependencies.png b/figures/dependencies.png new file mode 100644 index 0000000000000000000000000000000000000000..c065453a563e0c8797d3b848f64557f9e73dc23a GIT binary patch literal 3571 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 literal 0 HcmV?d00001 diff --git a/figures/dependencies.svg b/figures/dependencies.svg new file mode 100644 index 0000000..6e50663 --- /dev/null +++ b/figures/dependencies.svg @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +