From f9012e8d1c0fa7d07f09d21adde5e97439ed1d14 Mon Sep 17 00:00:00 2001 From: Will Heslam Date: Mon, 6 Jun 2022 14:07:12 +0100 Subject: [PATCH] Alternative: add getAlternativeMonoid --- docs/modules/Alternative.ts.md | 31 +++++++++++++++++++++++++++++ src/Alternative.ts | 36 ++++++++++++++++++++++++++++++++++ test/Alternative.ts | 20 +++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/docs/modules/Alternative.ts.md b/docs/modules/Alternative.ts.md index 1efd9c7fb..1f109a2d1 100644 --- a/docs/modules/Alternative.ts.md +++ b/docs/modules/Alternative.ts.md @@ -35,6 +35,7 @@ Added in v2.0.0 - [Alternative4 (interface)](#alternative4-interface) - [utils](#utils) - [altAll](#altall) + - [getAlternativeMonoid](#getalternativemonoid) --- @@ -137,3 +138,33 @@ export declare function altAll(F: Alternative): (as: ReadonlyArray( + F: Alternative4 +): (S: Semigroup) => Monoid> +export declare function getAlternativeMonoid( + F: Alternative3 +): (S: Semigroup) => Monoid> +export declare function getAlternativeMonoid( + F: Alternative3C +): (S: Semigroup) => Monoid> +export declare function getAlternativeMonoid( + F: Alternative2 +): (S: Semigroup) => Monoid> +export declare function getAlternativeMonoid( + F: Alternative2C +): (S: Semigroup) => Monoid> +export declare function getAlternativeMonoid( + F: Alternative1 +): (S: Semigroup) => Monoid> +export declare function getAlternativeMonoid(F: Alternative): (S: Semigroup) => Monoid> +``` + +Added in v2.13.0 diff --git a/src/Alternative.ts b/src/Alternative.ts index 69d151870..384ea72f2 100644 --- a/src/Alternative.ts +++ b/src/Alternative.ts @@ -24,8 +24,11 @@ import { Applicative3C, Applicative4 } from './Applicative' +import { getApplySemigroup } from './Apply' import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' import { Zero, Zero1, Zero2, Zero2C, Zero3, Zero3C, Zero4 } from './Zero' +import { Monoid } from './Monoid' +import { Semigroup } from './Semigroup' // ------------------------------------------------------------------------------------- // model @@ -98,3 +101,36 @@ export function altAll(F: Alternative): (as: ReadonlyArray>) export function altAll(F: Alternative): (as: ReadonlyArray>) => HKT { return altAll_(F)(F.zero()) } + +/** + * Lift a semigroup into a monoid alternative 'F', the inner values are concatenated using the provided `Semigroup`. + * @since 2.13.0 + */ +export function getAlternativeMonoid( + F: Alternative4 +): (S: Semigroup) => Monoid> +export function getAlternativeMonoid( + F: Alternative3 +): (S: Semigroup) => Monoid> +export function getAlternativeMonoid( + F: Alternative3C +): (S: Semigroup) => Monoid> +export function getAlternativeMonoid( + F: Alternative2 +): (S: Semigroup) => Monoid> +export function getAlternativeMonoid( + F: Alternative2C +): (S: Semigroup) => Monoid> +export function getAlternativeMonoid(F: Alternative1): (S: Semigroup) => Monoid> +export function getAlternativeMonoid(F: Alternative): (S: Semigroup) => Monoid> +export function getAlternativeMonoid(F: Alternative): (S: Semigroup) => Monoid> { + const f = getApplySemigroup(F) + return (S: Semigroup) => { + const SF = f(S) + return { + concat: (first: HKT, second: HKT) => + F.alt(SF.concat(first, second), () => F.alt(first, () => second)), + empty: F.zero() + } + } +} diff --git a/test/Alternative.ts b/test/Alternative.ts index 6548595f8..030103cab 100644 --- a/test/Alternative.ts +++ b/test/Alternative.ts @@ -1,5 +1,8 @@ import * as _ from '../src/Alternative' +import * as M from '../src/Monoid' +import * as NEA from '../src/NonEmptyArray' import * as O from '../src/Option' +import * as S from '../src/Semigroup' import * as U from './util' describe('Alternative', () => { @@ -9,4 +12,21 @@ describe('Alternative', () => { U.deepStrictEqual(altAll([O.none]), O.none) U.deepStrictEqual(altAll([O.none, O.some(1)]), O.some(1)) }) + + it('getAlternativeMonoid', () => { + const altConcatAll = M.concatAll(_.getAlternativeMonoid(O.Alternative)(NEA.getSemigroup())) + U.deepStrictEqual(altConcatAll([]), O.none) + U.deepStrictEqual(altConcatAll([O.none]), O.none) + U.deepStrictEqual(altConcatAll([O.none, O.some([1]), O.some([2])]), O.some([1, 2])) + + const pickFirst = _.getAlternativeMonoid(O.Alternative)(S.first()) + U.deepStrictEqual(pickFirst.concat(O.some('a'), O.some('b')), O.some('a')) + U.deepStrictEqual(pickFirst.concat(O.none, O.some('b')), O.some('b')) + U.deepStrictEqual(pickFirst.concat(O.some('a'), O.none), O.some('a')) + + const pickLast = _.getAlternativeMonoid(O.Alternative)(S.last()) + U.deepStrictEqual(pickLast.concat(O.some('a'), O.some('b')), O.some('b')) + U.deepStrictEqual(pickLast.concat(O.none, O.some('b')), O.some('b')) + U.deepStrictEqual(pickLast.concat(O.some('a'), O.none), O.some('a')) + }) })