Skip to content

Commit

Permalink
Merge pull request #62 from sanctuary-js/davidchambers/append-prepend
Browse files Browse the repository at this point in the history
derive ‘append’ and ‘prepend’ from ‘concat’ and ‘of’
  • Loading branch information
davidchambers authored Jun 20, 2017
2 parents e98b2e0 + 4e92083 commit d757289
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 3 deletions.
40 changes: 40 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,44 @@
return Applicative.methods.of(typeRep)(x);
}

//# append :: (Applicative f, Semigroup (f a)) => (a, f a) -> f a
//.
//. Returns the result of appending the first argument to the second.
//.
//. This function is derived from [`concat`](#concat) and [`of`](#of).
//.
//. See also [`prepend`](#prepend).
//.
//. ```javascript
//. > append(3, [1, 2])
//. [1, 2, 3]
//.
//. > append(3, Cons(1, Cons(2, Nil)))
//. Cons(1, Cons(2, Cons(3, Nil)))
//. ```
function append(x, xs) {
return concat(xs, of(xs.constructor, x));
}

//# prepend :: (Applicative f, Semigroup (f a)) => (a, f a) -> f a
//.
//. Returns the result of prepending the first argument to the second.
//.
//. This function is derived from [`concat`](#concat) and [`of`](#of).
//.
//. See also [`append`](#append).
//.
//. ```javascript
//. > prepend(1, [2, 3])
//. [1, 2, 3]
//.
//. > prepend(1, Cons(2, Cons(3, Nil)))
//. Cons(1, Cons(2, Cons(3, Nil)))
//. ```
function prepend(x, xs) {
return concat(of(xs.constructor, x), xs);
}

//# chain :: Chain m => (a -> m b, m a) -> m b
//.
//. Function wrapper for [`fantasy-land/chain`][].
Expand Down Expand Up @@ -1893,6 +1931,8 @@
apFirst: apFirst,
apSecond: apSecond,
of: of,
append: append,
prepend: prepend,
chain: chain,
join: join,
chainRec: chainRec,
Expand Down
20 changes: 17 additions & 3 deletions test/Maybe.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ function _Maybe(tag, value) {
this.isNothing = tag === 'Nothing';
this.isJust = tag === 'Just';
if (this.isJust) this.value = value;

if (this.isNothing || Z.Setoid.test(this.value)) {
this[FL.equals] = Maybe$prototype$equals;
}

if (this.isNothing || Z.Semigroup.test(this.value)) {
this[FL.concat] = Maybe$prototype$concat;
}
}

Maybe['@@type'] = 'sanctuary-type-classes/Maybe';
Expand All @@ -27,10 +35,16 @@ Maybe[FL.of] = Maybe.Just;

Maybe[FL.zero] = Maybe[FL.empty];

Maybe.prototype[FL.equals] = function(other) {
function Maybe$prototype$equals(other) {
return this.isNothing ? other.isNothing
: other.isJust && Z.equals(other.value, this.value);
};
: other.isJust && Z.equals(this.value, other.value);
}

function Maybe$prototype$concat(other) {
return this.isNothing ? other :
other.isNothing ? this :
/* otherwise */ Maybe.Just(Z.concat(this.value, other.value));
}

Maybe.prototype[FL.map] = function(f) {
return this.isJust ? Maybe.Just(f(this.value)) : Maybe.Nothing;
Expand Down
26 changes: 26 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,32 @@ test('of', function() {
eq(Z.of(Maybe, 42), Just(42));
});

test('append', function() {
eq(Z.append.length, 2);
eq(Z.append.name, 'append');

eq(Z.append(3, []), [3]);
eq(Z.append(3, [1, 2]), [1, 2, 3]);
eq(Z.append(3, Nil), Cons(3, Nil));
eq(Z.append(3, Cons(1, Cons(2, Nil))), Cons(1, Cons(2, Cons(3, Nil))));
eq(Z.append([5, 6], [[1, 2], [3, 4]]), [[1, 2], [3, 4], [5, 6]]);
eq(Z.append([2], Nothing), Just([2]));
eq(Z.append([2], Just([1])), Just([1, 2]));
});

test('prepend', function() {
eq(Z.prepend.length, 2);
eq(Z.prepend.name, 'prepend');

eq(Z.prepend(1, []), [1]);
eq(Z.prepend(1, [2, 3]), [1, 2, 3]);
eq(Z.prepend(1, Nil), Cons(1, Nil));
eq(Z.prepend(1, Cons(2, Cons(3, Nil))), Cons(1, Cons(2, Cons(3, Nil))));
eq(Z.prepend([1, 2], [[3, 4], [5, 6]]), [[1, 2], [3, 4], [5, 6]]);
eq(Z.prepend([1], Nothing), Just([1]));
eq(Z.prepend([1], Just([2])), Just([1, 2]));
});

test('chain', function() {
eq(Z.chain.length, 2);
eq(Z.chain.name, 'chain');
Expand Down

0 comments on commit d757289

Please sign in to comment.