Skip to content

Commit

Permalink
Implement S.add and S.subtract
Browse files Browse the repository at this point in the history
  • Loading branch information
svozza committed Jan 26, 2016
1 parent b4e3b97 commit 90e9689
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 21 deletions.
31 changes: 31 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@

// env :: [Type]
var env = $.env.concat([
$.FiniteNumber,
$Either,
Integer,
List,
Expand Down Expand Up @@ -2195,6 +2196,36 @@
return filter(is(type), Just(x));
});

//. ### Numeric

//# add :: FiniteNumber -> FiniteNumber -> FiniteNumber
//.
//. Adds two finite numbers together.
//.
//. ```javascript
//. > S.add(1, 1);
//. 2
//. ```
S.add =
def('add',
{},
[$.FiniteNumber, $.FiniteNumber, $.FiniteNumber],
function(a, b) { return a + b; });

//# subtract :: FiniteNumber -> FiniteNumber -> FiniteNumber
//.
//. Subtracts one finite number from another.
//.
//. ```javascript
//. > S.subtract(2, 1);
//. 1
//. ```
S.subtract =
def('subtract',
{},
[$.FiniteNumber, $.FiniteNumber, $.FiniteNumber],
function(a, b) { return a - b; });

//. ### Parse

//# parseDate :: String -> Maybe Date
Expand Down
132 changes: 111 additions & 21 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,8 @@ describe('maybe', function() {
assert.throws(function() { S.Nothing().concat(S.Just(1)); },
errorEq(TypeError,
'‘Maybe#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));
});

it('provides an "equals" method', function() {
Expand Down Expand Up @@ -735,17 +736,20 @@ describe('maybe', function() {
assert.throws(function() { S.Just(1).concat(S.Just(0)); },
errorEq(TypeError,
'‘Maybe#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Just(2).concat(S.Just([1, 2, 3])); },
errorEq(TypeError,
'‘Maybe#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Just([1, 2, 3]).concat(S.Just(3)); },
errorEq(TypeError,
'‘Maybe#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));
});

it('provides an "equals" method', function() {
Expand Down Expand Up @@ -979,8 +983,9 @@ describe('maybe', function() {
assert.throws(function() { S.fromMaybe(0, [1, 2, 3]); },
errorEq(TypeError,
'‘fromMaybe’ expected a value of type ' +
'(Maybe Number) or (Maybe Integer) ' +
'as its second argument; received [1, 2, 3]'));
'(Maybe Number) or (Maybe FiniteNumber) or ' +
'(Maybe Integer) as its second argument; ' +
'received [1, 2, 3]'));
});

it('can be applied to a Nothing', function() {
Expand Down Expand Up @@ -1272,32 +1277,38 @@ describe('either', function() {
assert.throws(function() { S.Left(1).concat(S.Left(0)); },
errorEq(TypeError,
'‘Either#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Left(2).concat(S.Right(0)); },
errorEq(TypeError,
'‘Either#concat’ requires ‘b’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Left(3).concat(S.Left([1, 2, 3])); },
errorEq(TypeError,
'‘Either#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Left(4).concat(S.Right([1, 2, 3])); },
errorEq(TypeError,
'‘Either#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Left([1, 2, 3]).concat(S.Left(5)); },
errorEq(TypeError,
'‘Either#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));;

assert.throws(function() { S.Left([1, 2, 3]).concat(S.Right(6)); },
errorEq(TypeError,
'‘Either#concat’ requires ‘b’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));
});

it('provides an "equals" method', function() {
Expand Down Expand Up @@ -1475,32 +1486,38 @@ describe('either', function() {
assert.throws(function() { S.Right(1).concat(S.Left(0)); },
errorEq(TypeError,
'‘Either#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Right(2).concat(S.Right(0)); },
errorEq(TypeError,
'‘Either#concat’ requires ‘b’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Right(3).concat(S.Left([1, 2, 3])); },
errorEq(TypeError,
'‘Either#concat’ requires ‘b’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Right(4).concat(S.Right([1, 2, 3])); },
errorEq(TypeError,
'‘Either#concat’ requires ‘b’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Right([1, 2, 3]).concat(S.Left(5)); },
errorEq(TypeError,
'‘Either#concat’ requires ‘a’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));

assert.throws(function() { S.Right([1, 2, 3]).concat(S.Right(6)); },
errorEq(TypeError,
'‘Either#concat’ requires ‘b’ to implement ' +
'Semigroup; Number and Integer do not'));
'Semigroup; Number and FiniteNumber and Integer ' +
'do not'));
});

it('provides an "equals" method', function() {
Expand Down Expand Up @@ -1991,7 +2008,7 @@ describe('alternative', function() {
assert.throws(function() { S.and(0, 1); },
errorEq(TypeError,
'‘and’ requires ‘a’ to implement Alternative; ' +
'Number and Integer do not'));
'Number and FiniteNumber and Integer do not'));
});

it('is curried', function() {
Expand Down Expand Up @@ -2053,7 +2070,7 @@ describe('alternative', function() {
assert.throws(function() { S.or(0, 1); },
errorEq(TypeError,
'‘or’ requires ‘a’ to implement Alternative; ' +
'Number and Integer do not'));
'Number and FiniteNumber and Integer do not'));
});

it('is curried', function() {
Expand Down Expand Up @@ -2108,12 +2125,14 @@ describe('alternative', function() {
errorEq(TypeError,
'‘xor’ requires ‘a’ to implement Alternative ' +
'and Monoid; (Either ??? Number) and ' +
'(Either ??? FiniteNumber) and ' +
'(Either ??? Integer) do not'));

assert.throws(function() { S.xor(S.Right(42), S.Right(43)); },
errorEq(TypeError,
'‘xor’ requires ‘a’ to implement Alternative ' +
'and Monoid; (Either ??? Number) and ' +
'(Either ??? FiniteNumber) and ' +
'(Either ??? Integer) do not'));
});

Expand All @@ -2134,7 +2153,8 @@ describe('alternative', function() {
assert.throws(function() { S.xor(0, 1); },
errorEq(TypeError,
'‘xor’ requires ‘a’ to implement Alternative ' +
'and Monoid; Number and Integer do not'));
'and Monoid; Number and FiniteNumber and Integer ' +
'do not'));
});

it('is curried', function() {
Expand Down Expand Up @@ -3086,6 +3106,76 @@ describe('object', function() {

});

describe('numeric', function() {

describe('add', function() {

it('is a binary function', function() {
eq(typeof S.add, 'function');
eq(S.add.length, 2);
});

it('type checks its arguments', function() {
assert.throws(function() { S.add('xxx', 1); },
errorEq(TypeError,
'‘add’ expected a value of type FiniteNumber ' +
'as its first argument; received "xxx"'));

assert.throws(function() { S.add(1, 'xxx'); },
errorEq(TypeError,
'‘add’ expected a value of type FiniteNumber ' +
'as its second argument; received "xxx"'));
});

it('adds two numbers', function() {
eq(S.add(1, 1), 2);
eq(S.add(-1, -1), -2);
eq(S.add(1.5, 1), 2.5);
eq(S.add(-1.5, -1), -2.5);
});

it('is curried', function() {
eq(S.add(1).length, 1);
eq(S.add(1)(1), 2);
});

});

describe('subtract', function() {

it('is a binary function', function() {
eq(typeof S.subtract, 'function');
eq(S.subtract.length, 2);
});

it('type checks its arguments', function() {
assert.throws(function() { S.subtract('xxx', 1); },
errorEq(TypeError,
'‘subtract’ expected a value of type FiniteNumber ' +
'as its first argument; received "xxx"'));

assert.throws(function() { S.subtract(1, 'xxx'); },
errorEq(TypeError,
'‘subtract’ expected a value of type FiniteNumber ' +
'as its second argument; received "xxx"'));
});

it('adds subtracts numbers', function() {
eq(S.subtract(1, 1), 0);
eq(S.subtract(-1, -1), 0);
eq(S.subtract(7.5, 2), 5.5);
eq(S.subtract(-7.5, -2), -5.5);
});

it('is curried', function() {
eq(S.subtract(1).length, 1);
eq(S.subtract(1)(1), 0);
});

});

});

describe('parse', function() {

describe('parseDate', function() {
Expand Down

0 comments on commit 90e9689

Please sign in to comment.