From 9e325db34e77ad5e6a8fec065c7249ed56ee55b0 Mon Sep 17 00:00:00 2001 From: David Chambers Date: Tue, 2 Feb 2016 17:47:34 -0800 Subject: [PATCH] either: add S.lefts and S.rights --- index.js | 36 ++++++++++++++++++++++++++++++++++++ test/index.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/index.js b/index.js index 7d621481..0d648c7f 100644 --- a/index.js +++ b/index.js @@ -1490,6 +1490,42 @@ return either.isLeft ? l(either.value) : r(either.value); }); + //# lefts :: [Either a b] -> [a] + //. + //. Takes a list of Eithers and returns a list containing each Left's value. + //. + //. See also [`rights`](#rights). + //. + //. ```javascript + //. > S.lefts([S.Right(20), S.Left('foo'), S.Right(10), S.Left('bar')]) + //. ['foo', 'bar'] + //. ``` + S.lefts = + def('lefts', + {}, + [$.Array($Either(a, b)), $.Array(a)], + R.chain(function(either) { + return either.isLeft ? [either.value] : []; + })); + + //# rights :: [Either a b] -> [b] + //. + //. Takes a list of Eithers and returns a list containing each Right's value. + //. + //. See also [`lefts`](#lefts). + //. + //. ```javascript + //. > S.rights([S.Right(20), S.Left('foo'), S.Right(10), S.Left('bar')]) + //. [20, 10] + //. ``` + S.rights = + def('rights', + {}, + [$.Array($Either(a, b)), $.Array(b)], + R.chain(function(either) { + return either.isRight ? [either.value] : []; + })); + //# encaseEither :: (Error -> l) -> (a -> r) -> a -> Either l r //. //. Takes two unary functions, `f` and `g`, the second of which may throw, diff --git a/test/index.js b/test/index.js index c0bb8090..53c510a3 100644 --- a/test/index.js +++ b/test/index.js @@ -1919,6 +1919,56 @@ describe('either', function() { }); + describe('lefts', function() { + + it('is a unary function', function() { + eq(typeof S.lefts, 'function'); + eq(S.lefts.length, 1); + }); + + it('type checks its arguments', function() { + assert.throws(function() { S.lefts([1, 2, 3]); }, + errorEq(TypeError, + '‘lefts’ expected a value of type ' + + '(Array (Either a b)) as its first argument; ' + + 'received [1, 2, 3]')); + }); + + it('returns a list containing the value of each Left', function() { + eq(S.lefts([]), []); + eq(S.lefts([S.Right(2), S.Right(1)]), []); + eq(S.lefts([S.Right(2), S.Left('b')]), ['b']); + eq(S.lefts([S.Left('a'), S.Right(1)]), ['a']); + eq(S.lefts([S.Left('a'), S.Left('b')]), ['a', 'b']); + }); + + }); + + describe('rights', function() { + + it('is a unary function', function() { + eq(typeof S.rights, 'function'); + eq(S.rights.length, 1); + }); + + it('type checks its arguments', function() { + assert.throws(function() { S.rights([1, 2, 3]); }, + errorEq(TypeError, + '‘rights’ expected a value of type ' + + '(Array (Either a b)) as its first argument; ' + + 'received [1, 2, 3]')); + }); + + it('returns a list containing the value of each Right', function() { + eq(S.rights([]), []); + eq(S.rights([S.Left('a'), S.Left('b')]), []); + eq(S.rights([S.Left('a'), S.Right(1)]), [1]); + eq(S.rights([S.Right(2), S.Left('b')]), [2]); + eq(S.rights([S.Right(2), S.Right(1)]), [2, 1]); + }); + + }); + describe('encaseEither', function() { it('is a ternary function', function() {