Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[email protected] compatibility #131

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"test": "mocha"
},
"dependencies": {
"ramda": ">=0.15.0"
"ramda": ">=0.15.0",
"sanctuary-type-classes": "0.2.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just published v0.3.0. :)

},
"devDependencies": {
"jscs": "1.13.x",
Expand Down
5 changes: 5 additions & 0 deletions src/Either.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,10 @@ Either.Left = function(value) {
return new _Left(value);
};

require('./internal/fl-patch')([
Either, Either.prototype,
_Left, _Left.prototype,
_Right, _Right.prototype,
]);

module.exports = Either;
2 changes: 2 additions & 0 deletions src/Future.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,6 @@ Future.cache = function(f) {
});
};

require('./internal/fl-patch')([Future, Future.prototype]);

module.exports = Future;
9 changes: 6 additions & 3 deletions src/IO.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var compose = require('ramda/src/compose');
var toString = require('ramda/src/toString');
var Z = require('sanctuary-type-classes');

var util = require('./internal/util');

Expand Down Expand Up @@ -42,9 +43,9 @@ IO.prototype.map = function(f) {
// `this` IO must wrap a function `f` that takes an IO (`thatIo`) as input
// `f` must return an IO
IO.prototype.ap = function(thatIo) {
return this.chain(function(f) {
return thatIo.map(f);
});
return Z.chain(function(f) {
return Z.map(f, thatIo);
}, this);
};

IO.runIO = function(io) {
Expand All @@ -64,3 +65,5 @@ IO.of = IO.prototype.of;
IO.prototype.toString = function() {
return 'IO(' + toString(this.fn) + ')';
};

require('./internal/fl-patch')([IO, IO.prototype]);
6 changes: 4 additions & 2 deletions src/Identity.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var toString = require('ramda/src/toString');

var Z = require('sanctuary-type-classes');
var util = require('./internal/util');


Expand Down Expand Up @@ -52,7 +52,7 @@ Identity.prototype.map = function(f) {
* @sig (Identity[a -> b], f: Applicative[_]) => f[a] -> f[b]
*/
Identity.prototype.ap = function(app) {
return app.map(this.value);
return Z.map(this.value, app);
};

/**
Expand Down Expand Up @@ -94,4 +94,6 @@ Identity.prototype.toString = function() {
return 'Identity(' + toString(this.value) + ')';
};

require('./internal/fl-patch')([Identity, Identity.prototype]);

module.exports = Identity;
17 changes: 12 additions & 5 deletions src/Maybe.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var toString = require('ramda/src/toString');
var curry = require('ramda/src/curry');
var Z = require('sanctuary-type-classes');

var util = require('./internal/util.js');

Expand Down Expand Up @@ -46,23 +47,23 @@ Maybe.isNothing = function(x) {
};

Maybe.maybe = curry(function(nothingVal, justFn, m) {
return m.reduce(function(_, x) {
return Z.reduce(function(_, x) {
return justFn(x);
}, nothingVal);
}, nothingVal, m);
});

// semigroup
Just.prototype.concat = function(that) {
return that.isNothing ? this : this.of(
this.value.concat(that.value)
Z.concat(this.value, that.value)
);
};

Nothing.prototype.concat = util.identity;

// functor
Just.prototype.map = function(f) {
return this.of(f(this.value));
return Z.of(this, f(this.value));
};

Nothing.prototype.map = util.returnThis;
Expand All @@ -71,7 +72,7 @@ Nothing.prototype.map = util.returnThis;
// takes a Maybe that wraps a function (`app`) and applies its `map`
// method to this Maybe's value, which must be a function.
Just.prototype.ap = function(m) {
return m.map(this.value);
return Z.map(this.value, m);
};

Nothing.prototype.ap = util.returnThis;
Expand Down Expand Up @@ -151,4 +152,10 @@ Nothing.prototype.toString = function() {
return 'Maybe.Nothing()';
};

require('./internal/fl-patch')([
Maybe, Maybe.prototype,
Nothing, Nothing.prototype,
Just, Just.prototype,
]);

module.exports = Maybe;
32 changes: 19 additions & 13 deletions src/Reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ var compose = require('ramda/src/compose');
var identity = require('ramda/src/identity');
var toString = require('ramda/src/toString');
var always = require('ramda/src/always');
var Z = require('sanctuary-type-classes');

var patchAll = require('./internal/fl-patch');

function Reader(run) {
if (!(this instanceof Reader)) {
Expand All @@ -25,15 +27,15 @@ Reader.prototype.chain = function(f) {
};

Reader.prototype.ap = function(a) {
return this.chain(function(f) {
return a.map(f);
});
return Z.chain(function(f) {
return Z.map(f, a);
}, this);
};

Reader.prototype.map = function(f) {
return this.chain(function(a) {
return Reader.of(f(a));
});
return Z.chain(function(a) {
return Z.of(Reader, f(a));
}, this);
};

Reader.prototype.of = function(a) {
Expand Down Expand Up @@ -63,38 +65,42 @@ Reader.T = function(M) {

ReaderT.prototype.of = ReaderT.of = function(a) {
return ReaderT(function() {
return M.of(a);
return Z.of(M, a);
});
};

ReaderT.prototype.chain = function(f) {
var readerT = this;
return ReaderT(function(e) {
var m = readerT.run(e);
return m.chain(function(a) {
return Z.chain(function(a) {
return f(a).run(e);
});
}, m);
});
};

ReaderT.prototype.map = function(f) {
return this.chain(function(a) {
return ReaderT.of(f(a));
});
return Z.chain(function(a) {
return Z.of(ReaderT, f(a));
}, this);
};

ReaderT.prototype.ap = function(a) {
var readerT = this;
return ReaderT(function(e) {
return readerT.run(e).ap(a.run(e));
return Z.ap(readerT.run(e), a.run(e));
});
};

ReaderT.prototype.toString = function() {
return 'ReaderT[' + M.name + '](' + toString(this.run) + ')';
};

patchAll([ReaderT, ReaderT.prototype]);

return ReaderT;
};

patchAll([Reader, Reader.prototype]);

module.exports = Reader;
34 changes: 20 additions & 14 deletions src/State.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
var curry = require('ramda/src/curry');
var Z = require('sanctuary-type-classes');

var Identity = require('./Identity');
var Tuple = require('./Tuple');
var util = require('./internal/util');

var patchAll = require('./internal/fl-patch');

function T(M) {
function StateT(run) {
Expand All @@ -24,56 +25,59 @@ function T(M) {
StateT.prototype.chain = function(f) {
var state = this;
return StateT(function(s) {
return state._run(s).chain(function(t) {
return Z.chain(function(t) {
return f(Tuple.fst(t))._run(Tuple.snd(t));
});
}, state._run(s));
});
};
StateT.of = StateT.prototype.of = function(a) {
return StateT(function (s) {
return M.of(Tuple(a, s));
return Z.of(M,Tuple(a, s));
});
};
StateT.prototype.ap = util.deriveAp(StateT);
StateT.prototype.map = util.deriveMap(StateT);
StateT.tailRec = curry(function(stepFn, init) {
return StateT(function(s) {
return M.tailRec(function(t) {
return stepFn(Tuple.fst(t))._run(Tuple.snd(t)).chain(function (t_) {
return M.of(Tuple.fst(t_).bimap(
return Z.chain(function (t_) {
return Z.of(M,Z.bimap(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/M,Z/M, Z/

function(a) { return Tuple(a, Tuple.snd(t_)); },
function(b) { return Tuple(b, Tuple.snd(t_)); }
function(b) { return Tuple(b, Tuple.snd(t_)); },
Tuple.fst(t_)
));
});
}, stepFn(Tuple.fst(t))._run(Tuple.snd(t)));
}, Tuple(init, s));
});
});
StateT.lift = function(ma) {
return StateT(function(s) {
return ma.chain(function(a) {
return M.of(Tuple(a, s));
return Z.chain(ma, function(a) {
return Z.of(M, Tuple(a, s));
});
});
};
StateT.get = StateT(function(s) {
return M.of(Tuple(s, s));
return Z.of(M, Tuple(s, s));
});
StateT.gets = function(f) {
return StateT(function(s) {
return M.of(Tuple(f(s), s));
return Z.of(M, Tuple(f(s), s));
});
};
StateT.put = function(s) {
return StateT(function(_) {
return M.of(Tuple(void _, s));
return Z.of(M, Tuple(void _, s));
});
};
StateT.modify = function(f) {
return StateT(function(s) {
return M.of(Tuple(void 0, f(s)));
return Z.of(M, Tuple(void 0, f(s)));
});
};

patchAll([StateT, StateT.prototype]);

return StateT;
}

Expand All @@ -83,4 +87,6 @@ State.prototype.run = function(s) {
return this._run(s).value;
};

patchAll([State, State.prototype]);

module.exports = State;
18 changes: 6 additions & 12 deletions src/Tuple.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var toString = require('ramda/src/toString');
var equals = require('ramda/src/equals');
var Z = require('sanctuary-type-classes');


function Tuple(x, y) {
Expand All @@ -21,14 +22,6 @@ function _Tuple(x, y) {
this.length = 2;
}

function ensureConcat(xs) {
xs.forEach(function(x) {
if (typeof x.concat != 'function') {
throw new TypeError(toString(x) + ' must be a semigroup to perform this operation');
}
});
}

Tuple.fst = function(x) {
return x[0];
};
Expand All @@ -41,8 +34,7 @@ _Tuple.prototype['@@type'] = 'ramda-fantasy/Tuple';

// semigroup
_Tuple.prototype.concat = function(x) {
ensureConcat([this[0], this[1]]);
return Tuple(this[0].concat(x[0]), this[1].concat(x[1]));
return Tuple(Z.concat(this[0], x[0]), Z.concat(this[1], x[1]));
};

// functor
Expand All @@ -52,8 +44,7 @@ _Tuple.prototype.map = function(f) {

// apply
_Tuple.prototype.ap = function(m) {
ensureConcat([this[0]]);
return Tuple(this[0].concat(m[0]), this[1](m[1]));
return Tuple(Z.concat(this[0], m[0]), this[1](m[1]));
};

// setoid
Expand All @@ -65,4 +56,7 @@ _Tuple.prototype.toString = function() {
return 'Tuple(' + toString(this[0]) + ', ' + toString(this[1]) + ')';
};

require('./internal/fl-patch')([_Tuple, _Tuple.prototype]);


module.exports = Tuple;
22 changes: 22 additions & 0 deletions src/internal/fl-patch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var fl = require('./fl.js');
var fixedAp = function(f) {
return f.ap(this);
};

var patch = function(obj){
return Object.keys(fl).forEach(function(key) {
if (typeof obj[key] === 'function') {
if (key === 'ap') {
obj[fl[key]] = fixedAp;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't feel right to me. What would be the consequences of removing this exception?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing this means we should revert ap of all structures

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the way the existing ap methods behave, do you mean? I think we should do so. Having an ap method with the old behaviour is confusing.

} else {
obj[fl[key]] = obj[key];
}
}
});
};

var patchAll = function(objs){
return objs.forEach(patch);
};

module.exports = patchAll;
16 changes: 16 additions & 0 deletions src/internal/fl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
equals: 'fantasy-land/equals',
concat: 'fantasy-land/concat',
empty: 'fantasy-land/empty',
map: 'fantasy-land/map',
ap: 'fantasy-land/ap',
of: 'fantasy-land/of',
reduce: 'fantasy-land/reduce',
traverse: 'fantasy-land/traverse',
chain: 'fantasy-land/chain',
chainRec: 'fantasy-land/chainRec',
extend: 'fantasy-land/extend',
extract: 'fantasy-land/extract',
bimap: 'fantasy-land/bimap',
promap: 'fantasy-land/promap',
};
Loading