diff --git a/src/Semigroup.ts b/src/Semigroup.ts index 97c2e7167..79ad8c430 100644 --- a/src/Semigroup.ts +++ b/src/Semigroup.ts @@ -177,3 +177,22 @@ export const semigroupString: Semigroup = { export const semigroupVoid: Semigroup = { concat: () => undefined } + +/** + * You can glue items between and stay associative + * + * @example + * import { getIntercalateSemigroup, semigroupString } from 'fp-ts/lib/Semigroup' + * + * const S = getIntercalateSemigroup(' ')(semigroupString) + * + * assert.strictEqual(S.concat('a', 'b'), 'a b') + * assert.strictEqual(S.concat(S.concat('a', 'b'), 'c'), S.concat('a', S.concat('b', 'c'))) + * + * @since 2.5.0 + */ +export function getIntercalateSemigroup(a: A): (S: Semigroup) => Semigroup { + return S => ({ + concat: (x, y) => S.concat(x, S.concat(a, y)) + }) +} diff --git a/test/Semigroup.ts b/test/Semigroup.ts index 80eed6733..e7bcb94b9 100644 --- a/test/Semigroup.ts +++ b/test/Semigroup.ts @@ -13,7 +13,8 @@ import { semigroupString, semigroupSum, semigroupVoid, - getDualSemigroup + getDualSemigroup, + getIntercalateSemigroup } from '../src/Semigroup' describe('Semigroup', () => { @@ -71,4 +72,10 @@ describe('Semigroup', () => { const S = getDualSemigroup(semigroupString) assert.deepStrictEqual(S.concat('a', 'b'), 'ba') }) + + it('getIntercalateSemigroup', () => { + const S = getIntercalateSemigroup(' ')(semigroupString) + assert.strictEqual(S.concat('a', 'b'), 'a b') + assert.strictEqual(S.concat(S.concat('a', 'b'), 'c'), S.concat('a', S.concat('b', 'c'))) + }) })