Skip to content

Commit

Permalink
@safareli's patch for S.chainRec
Browse files Browse the repository at this point in the history
  • Loading branch information
davidchambers committed Jan 21, 2017
1 parent 818ead2 commit 46a83e5
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
20 changes: 10 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -867,11 +867,11 @@
//. ```
S.join = def('join', {m: [Z.Chain]}, [m(m(a)), m(a)], Z.join);

//# chainRec :: ChainRec m => TypeRep m -> (a -> Either (m b) (m b)) -> a -> m b
//# chainRec :: ChainRec m => TypeRep m -> (a -> m (Either a b)) -> a -> m b
//.
//. Performs a [`chain`](#chain)-like computation with constant stack usage.
//. Similar to [`Z.chainRec`][], but curried and more convenient due to the
//. use of the Either type to indicate completion.
//. use of the Either type to indicate completion (via a Right).
//.
//. ```javascript
//. > S.chainRec(Array,
Expand All @@ -880,17 +880,17 @@
//. . '')
//. ['oo!', 'oo?', 'on!', 'on?', 'no!', 'no?', 'nn!', 'nn?']
//. ```
function chainRec(typeRep, f, x) {
function step(next, done, x) {
return Z.map(function(e) { return either(next, done, e); }, f(x));
}
return Z.chainRec(typeRep, step, x);
}
S.chainRec =
def('chainRec',
{m: [Z.ChainRec]},
[TypeRep($.TypeVariable('m')), Fn(a, $Either(m(b), m(b))), a, m(b)],
function(typeRep, f, x) {
function step(next, done, x) {
var either = f(x);
return Z.map(either.isLeft ? next : done, either.value);
}
return Z.chainRec(typeRep, step, x);
});
[TypeRep($.TypeVariable('m')), Fn(a, m($Either(a, b))), a, m(b)],
chainRec);

//# extend :: Extend w => (w a -> b) -> w a -> w b
//.
Expand Down
12 changes: 7 additions & 5 deletions test/chainRec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

var Z = require('sanctuary-type-classes');

var S = require('..');

var eq = require('./internal/eq');
Expand All @@ -9,18 +11,18 @@ test('chainRec', function() {

eq(typeof S.chainRec, 'function');
eq(S.chainRec.length, 3);
eq(S.chainRec.toString(), 'chainRec :: ChainRec m => TypeRep m -> (a -> Either (m b) (m b)) -> a -> m b');
eq(S.chainRec.toString(), 'chainRec :: ChainRec m => TypeRep m -> (a -> m (Either a b)) -> a -> m b');

function permute(s) {
return s.length === 2 ? S.Right([s + '!', s + '?'])
: S.Left([s + 'o', s + 'n']);
return s.length === 2 ? Z.map(S.Right, [s + '!', s + '?'])
: Z.map(S.Left, [s + 'o', s + 'n']);
}

eq(S.chainRec(Array, permute, ''), ['oo!', 'oo?', 'on!', 'on?', 'no!', 'no?', 'nn!', 'nn?']);

function stepper(n) {
return n === 3000 ? S.Right(function(env) { return n + env.inc; })
: S.Left(function(env) { return n + env.step; });
return n === 3000 ? Z.map(S.Right, function(env) { return n + env.inc; })
: Z.map(S.Left, function(env) { return n + env.step; });
}

eq(S.chainRec(Function, stepper, 0)({step: 2, inc: 100}), 3100);
Expand Down

0 comments on commit 46a83e5

Please sign in to comment.