Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
joneshf committed Jun 16, 2014
2 parents dfb40d4 + 1fa9a80 commit 7fc1a62
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 39 deletions.
72 changes: 55 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
This project specifies interoperability of common algebraic
structures:

* Setoid
* Semigroup
* Monoid
* Functor
* Apply
* Applicative
* Chain
* Monad

![](figures/dependencies.png)

## General

An algebra is a set of values, a set of operators that it is closed
Expand All @@ -37,6 +41,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)
Expand Down Expand Up @@ -93,37 +117,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`

### Applicative

A value that implements the Applicative specification must also
implement the Apply specification.

3. `ap` must apply the function in Applicative `a` to the value in
Applicative `b`
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

Expand All @@ -139,6 +169,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
Expand All @@ -164,7 +202,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)
Expand Down
67 changes: 67 additions & 0 deletions figures/dependencies.mp
Original file line number Diff line number Diff line change
@@ -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
Binary file added figures/dependencies.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7fc1a62

Please sign in to comment.