Skip to content

Commit

Permalink
Merge pull request #175 from plaid/dc-concat
Browse files Browse the repository at this point in the history
list: add S.concat
  • Loading branch information
davidchambers committed Apr 13, 2016
2 parents c09b210 + 175da4b commit d24b9bf
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 13 deletions.
25 changes: 23 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@
//. functions.
//.
//. ```javascript
//. > S.C(R.concat, 'foo', 'bar')
//. > S.C(S.concat, 'foo', 'bar')
//. 'barfoo'
//.
//. > R.filter(S.C(R.gt, 0), [-1, -2, 3, -4, 4, 2])
Expand Down Expand Up @@ -1968,6 +1968,27 @@

//. ### List

//# concat :: Semigroup a => a -> a -> a
//.
//. Concatenates two (homogeneous) arrays, two strings, or two values of any
//. other type which satisfies the [Semigroup][] specification.
//.
//. ```javascript
//. > S.concat([1, 2, 3], [4, 5, 6])
//. [1, 2, 3, 4, 5, 6]
//.
//. > S.concat('foo', 'bar')
//. 'foobar'
//.
//. > S.concat(S.Just('foo'), S.Just('bar'))
//. S.Just('foobar')
//. ```
var concat = S.concat =
def('concat',
{a: [Semigroup]},
[a, a, a],
function(x, y) { return x.concat(y); });

//# slice :: Integer -> Integer -> [a] -> Maybe [a]
//.
//. Returns Just a list containing the elements from the supplied list
Expand Down Expand Up @@ -2965,7 +2986,7 @@
def('unlines',
{},
[$.Array($.String), $.String],
compose(R.join(''), R.map(R.concat(_, '\n'))));
compose(R.join(''), R.map(concat(_, '\n'))));

return S;

Expand Down
92 changes: 81 additions & 11 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,14 +384,14 @@ describe('combinator', function() {
});

it('C(f, x, y) is equivalent to f(y)(x)', function() {
eq(S.C(R.concat, 'foo', 'bar'), 'barfoo');
eq(R.map(S.C(R.concat, '!'), ['BAM', 'POW', 'KA-POW']), ['BAM!', 'POW!', 'KA-POW!']);
eq(S.C(S.concat, 'foo', 'bar'), 'barfoo');
eq(R.map(S.C(S.concat, '!'), ['BAM', 'POW', 'KA-POW']), ['BAM!', 'POW!', 'KA-POW!']);
});

it('is curried', function() {
eq(S.C(R.concat).length, 2);
eq(S.C(R.concat)('foo').length, 1);
eq(S.C(R.concat)('foo')('bar'), 'barfoo');
eq(S.C(S.concat).length, 2);
eq(S.C(S.concat)('foo').length, 1);
eq(S.C(S.concat)('foo')('bar'), 'barfoo');
});

});
Expand Down Expand Up @@ -3207,6 +3207,76 @@ describe('logic', function() {

describe('list', function() {

describe('concat', function() {

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

it('type checks its arguments', function() {
throws(function() { S.concat(/XXX/); },
errorEq(TypeError,
'Type-class constraint violation\n' +
'\n' +
'concat :: Semigroup a => a -> a -> a\n' +
' ^^^^^^^^^^^ ^\n' +
' 1\n' +
'\n' +
'1) /XXX/ :: RegExp\n' +
'\n' +
'‘concat’ requires ‘a’ to satisfy the Semigroup type-class constraint; the value at position 1 does not.\n'));

throws(function() { S.concat('abc', [1, 2, 3]); },
errorEq(TypeError,
'Type-variable constraint violation\n' +
'\n' +
'concat :: Semigroup a => a -> a -> a\n' +
' ^ ^\n' +
' 1 2\n' +
'\n' +
'1) "abc" :: String\n' +
'\n' +
'2) [1, 2, 3] :: Array Number, Array FiniteNumber, Array NonZeroFiniteNumber, Array Integer, Array ValidNumber\n' +
'\n' +
'Since there is no type of which all the above values are members, the type-variable constraint has been violated.\n'));
});

it('can be applied to homogeneous arrays', function() {
eq(S.concat([], []), []);
eq(S.concat([1, 2, 3], []), [1, 2, 3]);
eq(S.concat([], [4, 5, 6]), [4, 5, 6]);
eq(S.concat([1, 2, 3], [4, 5, 6]), [1, 2, 3, 4, 5, 6]);
});

it('can be applied to strings', function() {
eq(S.concat('', ''), '');
eq(S.concat('foo', ''), 'foo');
eq(S.concat('', 'bar'), 'bar');
eq(S.concat('foo', 'bar'), 'foobar');
});

it('can be applied to maybes', function() {
eq(S.concat(S.Nothing(), S.Nothing()), S.Nothing());
eq(S.concat(S.Just('foo'), S.Nothing()), S.Just('foo'));
eq(S.concat(S.Nothing(), S.Just('bar')), S.Just('bar'));
eq(S.concat(S.Just('foo'), S.Just('bar')), S.Just('foobar'));
});

it('can be applied to eithers', function() {
eq(S.concat(S.Left('abc'), S.Left('def')), S.Left('abcdef'));
eq(S.concat(S.Right([1, 2, 3]), S.Left('def')), S.Right([1, 2, 3]));
eq(S.concat(S.Left('abc'), S.Right([4, 5, 6])), S.Right([4, 5, 6]));
eq(S.concat(S.Right([1, 2, 3]), S.Right([4, 5, 6])), S.Right([1, 2, 3, 4, 5, 6]));
});

it('is curried', function() {
eq(S.concat([1, 2, 3]).length, 1);
eq(S.concat([1, 2, 3])([4, 5, 6]), [1, 2, 3, 4, 5, 6]);
});

});

describe('at', function() {

it('is a binary function', function() {
Expand Down Expand Up @@ -4649,7 +4719,7 @@ describe('number', function() {
'‘min’ requires ‘a’ to satisfy the Ord type-class constraint; the value at position 1 does not.\n'));
});

it('may be applied to (valid) numbers', function() {
it('can be applied to (valid) numbers', function() {
eq(S.min(10, 2), 2);
eq(S.min(2, 10), 2);
eq(S.min(0.1, 0.01), 0.01);
Expand All @@ -4658,12 +4728,12 @@ describe('number', function() {
eq(S.min(-Infinity, Infinity), -Infinity);
});

it('may be applied to (valid) dates', function() {
it('can be applied to (valid) dates', function() {
eq(S.min(new Date(10), new Date(2)), new Date(2));
eq(S.min(new Date(2), new Date(10)), new Date(2));
});

it('may be applied to strings', function() {
it('can be applied to strings', function() {
eq(S.min('abc', 'xyz'), 'abc');
eq(S.min('xyz', 'abc'), 'abc');
eq(S.min('10', '2'), '10');
Expand Down Expand Up @@ -4724,7 +4794,7 @@ describe('number', function() {
'‘max’ requires ‘a’ to satisfy the Ord type-class constraint; the value at position 1 does not.\n'));
});

it('may be applied to (valid) numbers', function() {
it('can be applied to (valid) numbers', function() {
eq(S.max(10, 2), 10);
eq(S.max(2, 10), 10);
eq(S.max(0.1, 0.01), 0.1);
Expand All @@ -4733,12 +4803,12 @@ describe('number', function() {
eq(S.max(-Infinity, Infinity), Infinity);
});

it('may be applied to (valid) dates', function() {
it('can be applied to (valid) dates', function() {
eq(S.max(new Date(10), new Date(2)), new Date(10));
eq(S.max(new Date(2), new Date(10)), new Date(10));
});

it('may be applied to strings', function() {
it('can be applied to strings', function() {
eq(S.max('abc', 'xyz'), 'xyz');
eq(S.max('xyz', 'abc'), 'xyz');
eq(S.max('10', '2'), '2');
Expand Down

0 comments on commit d24b9bf

Please sign in to comment.