Skip to content

Commit

Permalink
Add profunctor spec
Browse files Browse the repository at this point in the history
  • Loading branch information
scott-christopher committed May 7, 2016
1 parent cabee1c commit 4a03779
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ structures:
* [Extend](#extend)
* [Comonad](#comonad)
* [Bifunctor](#bifunctor)
* [Profunctor](#profunctor)

<img src="figures/dependencies.png" width="677" height="212" />

Expand Down Expand Up @@ -419,8 +420,33 @@ method takes two arguments:
1. If `g` is not a function, the behaviour of `bimap` is unspecified.
### Profunctor
A value that implements the Profunctor specification must also implement
the Functor specification. The Profunctor specification is a contravariant
functor on its first type parameter and covariant functor on its second type
parameter.
1. `p.promap(a => a, b => b)` is equivalent to `p` (identity)
2. `p.promap(compose(f1)(f2), compose(g1)(g2))` is equivalent to `p.promap(f1, g1).promap(f2, g2)` (composition)
#### `promap` method
A value which has a Profunctor must provide a `promap` method.
The `profunctor` method takes two arguments:
c.promap(f, g)
1. `f` must be a function which returns a value
1. If `f` is not a function, the behaviour of `promap` is unspecified.
2. `f` can return any value.
2. `g` must be a function which returns a value
1. If `g` is not a function, the behaviour of `promap` is unspecified.
2. `g` can return any value.
## Notes
Expand Down
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ module.exports = {
chain: 'chain',
extend: 'extend',
extract: 'extract',
bimap: 'bimap'
bimap: 'bimap',
promap: 'promap'
}
28 changes: 28 additions & 0 deletions laws/profunctor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

const {identity, compose} = require('fantasy-combinators');
const {promap} = require('..');

/**
### Profunctor
1. `p.promap(a => a, b => b)` is equivalent to `p` (identity)
2. `p.promap(compose(f1)(f2), compose(g1)(g2))` is equivalent to `p.promap(f1, g1).promap(f2, g2)` (composition)
**/

const identityʹ = t => eq => x => {
const a = t(x)[promap](identity, identity);
const b = t(x);
return eq(a, b);
};

const composition = t => eq => x => {
const a = t(x)[promap](compose(identity)(identity), compose(identity)(identity));
const b = t(x)[promap](identity, identity)[promap](identity, identity);
return eq(a, b);
};

module.exports = { identity: identityʹ
, composition
};

0 comments on commit 4a03779

Please sign in to comment.