/** * A `Magma` is a pair `(A, concat)` in which `A` is a non-empty set and `concat` is a binary operation on `A` * * See [Semigroup](https://gcanti.github.io/fp-ts/modules/Semigroup.ts.html) for some instances. * * @since 2.0.0 */ // ------------------------------------------------------------------------------------- // combinators // ------------------------------------------------------------------------------------- /** * The dual of a `Magma`, obtained by swapping the arguments of `concat`. * * @example * import { reverse, concatAll } from 'fp-ts/Magma' * import * as N from 'fp-ts/number' * * const subAll = concatAll(reverse(N.MagmaSub))(0) * * assert.deepStrictEqual(subAll([1, 2, 3]), 2) * * @since 2.11.0 */ export var reverse = function (M) { return ({ concat: function (first, second) { return M.concat(second, first); } }); }; /** * @since 2.11.0 */ export var filterFirst = function (predicate) { return function (M) { return ({ concat: function (first, second) { return (predicate(first) ? M.concat(first, second) : second); } }); }; }; /** * @since 2.11.0 */ export var filterSecond = function (predicate) { return function (M) { return ({ concat: function (first, second) { return (predicate(second) ? M.concat(first, second) : first); } }); }; }; /** * @since 2.11.0 */ export var endo = function (f) { return function (M) { return ({ concat: function (first, second) { return M.concat(f(first), f(second)); } }); }; }; // ------------------------------------------------------------------------------------- // utils // ------------------------------------------------------------------------------------- /** * Given a sequence of `as`, concat them and return the total. * * If `as` is empty, return the provided `startWith` value. * * @example * import { concatAll } from 'fp-ts/Magma' * import * as N from 'fp-ts/number' * * const subAll = concatAll(N.MagmaSub)(0) * * assert.deepStrictEqual(subAll([1, 2, 3]), -6) * * @since 2.11.0 */ export var concatAll = function (M) { return function (startWith) { return function (as) { return as.reduce(function (a, acc) { return M.concat(a, acc); }, startWith); }; }; };