Skip to content

Commit

Permalink
either: add S.eitherToMaybe
Browse files Browse the repository at this point in the history
  • Loading branch information
davidchambers committed May 9, 2016
1 parent 2fb179d commit c66ba2a
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 28 deletions.
67 changes: 45 additions & 22 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1302,7 +1302,7 @@
//. Binary version of [`encase`](#encase).
//.
//. See also [`encase2_`](#encase2_).
S.encase2 =
var encase2 = S.encase2 =
def('encase2',
{},
[$.Function, a, b, $Maybe(c)],
Expand All @@ -1327,15 +1327,15 @@
return f_(x, y);
};
};
return S.encase2(f, x, y);
return encase2(f, x, y);
});

//# encase3 :: (a -> b -> c -> d) -> a -> b -> c -> Maybe d
//.
//. Ternary version of [`encase`](#encase).
//.
//. See also [`encase3_`](#encase3_).
S.encase3 =
var encase3 = S.encase3 =
def('encase3',
{},
[$.Function, a, b, c, $Maybe(d)],
Expand All @@ -1362,7 +1362,31 @@
};
};
};
return S.encase3(f, x, y, z);
return encase3(f, x, y, z);
});

//# maybeToEither :: a -> Maybe b -> Either a b
//.
//. Takes a value of any type and a Maybe, and returns an Either.
//. If the second argument is a Nothing, a Left containing the first
//. argument is returned. If the second argument is a Just, a Right
//. containing the Just's value is returned.
//.
//. See also [`eitherToMaybe`](#eitherToMaybe).
//.
//. ```javascript
//. > S.maybeToEither('Expecting an integer', S.parseInt(10, 'xyz'))
//. Left('Expecting an integer')
//.
//. > S.maybeToEither('Expecting an integer', S.parseInt(10, '42'))
//. Right(42)
//. ```
S.maybeToEither =
def('maybeToEither',
{},
[a, $Maybe(b), $Either(a, b)],
function(x, maybe) {
return maybe.isNothing ? Left(x) : Right(maybe.value);
});

//. ### Either type
Expand Down Expand Up @@ -1876,7 +1900,7 @@
//. Binary version of [`encaseEither`](#encaseEither).
//.
//. See also [`encaseEither2_`](#encaseEither2_).
S.encaseEither2 =
var encaseEither2 = S.encaseEither2 =
def('encaseEither2',
{},
[$.Function, $.Function, a, b, $Either(l, r)],
Expand All @@ -1902,15 +1926,15 @@
return g_(x, y);
};
};
return S.encaseEither2(f, g, x, y);
return encaseEither2(f, g, x, y);
});

//# encaseEither3 :: (Error -> l) -> (a -> b -> c -> r) -> a -> b -> c -> Either l r
//.
//. Ternary version of [`encaseEither`](#encaseEither).
//.
//. See also [`encaseEither3_`](#encaseEither3_).
S.encaseEither3 =
var encaseEither3 = S.encaseEither3 =
def('encaseEither3',
{},
[$.Function, $.Function, a, b, c, $Either(l, r)],
Expand Down Expand Up @@ -1938,29 +1962,28 @@
};
};
};
return S.encaseEither3(f, g, x, y, z);
return encaseEither3(f, g, x, y, z);
});

//# maybeToEither :: a -> Maybe b -> Either a b
//# eitherToMaybe :: Either a b -> Maybe b
//.
//. Takes a value of any type and a Maybe, and returns an Either.
//. If the second argument is a Nothing, a Left containing the first
//. argument is returned. If the second argument is a Just, a Right
//. containing the Just's value is returned.
//. Converts an Either to a Maybe. Left becomes Nothing; Right becomes Just.
//.
//. See also [`maybeToEither`](#maybeToEither).
//.
//. ```javascript
//. > S.maybeToEither('Expecting an integer', S.parseInt(10, 'xyz'))
//. Left('Expecting an integer')
//. > S.eitherToMaybe(S.Left('Cannot divide by zero'))
//. Nothing()
//.
//. > S.maybeToEither('Expecting an integer', S.parseInt(10, '42'))
//. Right(42)
//. > S.eitherToMaybe(S.Right(42))
//. Just(42)
//. ```
S.maybeToEither =
def('maybeToEither',
S.eitherToMaybe =
def('eitherToMaybe',
{},
[a, $Maybe(b), $Either(a, b)],
function(x, maybe) {
return maybe.isNothing ? Left(x) : Right(maybe.value);
[$Either(a, b), $Maybe(b)],
function(either) {
return either.isLeft ? Nothing() : Just(either.value);
});

//. ### Alternative
Expand Down
7 changes: 2 additions & 5 deletions test/Maybe/Maybe.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ var JustArb = function(arb) {
return arb.smap(S.Just, function(m) { return m.value; }, R.toString);
};

// eitherToMaybe :: Either a b -> Maybe b
var eitherToMaybe = S.either(S.K(S.Nothing()), S.Just);

// EitherArb :: Arbitrary a -> Arbitrary b -> Arbitrary (Either a b)
var EitherArb = function(lArb, rArb) {
return jsc.oneof(LeftArb(lArb), RightArb(rArb));
Expand Down Expand Up @@ -97,8 +94,8 @@ describe('Maybe', function() {

it('satisfies naturality', function() {
jsc.assert(jsc.forall(MaybeArb(EitherArb(jsc.integer, jsc.string)), function(maybe) {
var lhs = eitherToMaybe(maybe.sequence(S.Either.of));
var rhs = maybe.map(eitherToMaybe).sequence(S.Maybe.of);
var lhs = S.eitherToMaybe(maybe.sequence(S.Either.of));
var rhs = maybe.map(S.eitherToMaybe).sequence(S.Maybe.of);
return lhs.equals(rhs);
}));
});
Expand Down
39 changes: 39 additions & 0 deletions test/eitherToMaybe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

var throws = require('assert').throws;

var eq = require('./utils').eq;
var errorEq = require('./utils').errorEq;
var S = require('..');


describe('eitherToMaybe', function() {

it('is a unary function', function() {
eq(typeof S.eitherToMaybe, 'function');
eq(S.eitherToMaybe.length, 1);
});

it('type checks its arguments', function() {
throws(function() { S.eitherToMaybe('left'); },
errorEq(TypeError,
'Invalid value\n' +
'\n' +
'eitherToMaybe :: Either a b -> Maybe b\n' +
' ^^^^^^^^^^\n' +
' 1\n' +
'\n' +
'1) "left" :: String\n' +
'\n' +
'The value at position 1 is not a member of ‘Either a b’.\n'));
});

it('returns a Nothing when applied to a Left', function() {
eq(S.eitherToMaybe(S.Left('Cannot divide by zero')), S.Nothing());
});

it('returns a Just when applied to a Right', function() {
eq(S.eitherToMaybe(S.Right(42)), S.Just(42));
});

});
2 changes: 1 addition & 1 deletion test/match.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('match', function() {
S.Just([S.Just('bye'), S.Nothing()]));
});

it('returns a Nothing() if no match', function() {
it('returns a Nothing if no match', function() {
eq(S.match(/zzz/, 'abcdefg'), S.Nothing());
});

Expand Down

0 comments on commit c66ba2a

Please sign in to comment.