Skip to content

Commit

Permalink
Alternative: add getAlternativeMonoid
Browse files Browse the repository at this point in the history
  • Loading branch information
willheslam authored and gcanti committed Sep 9, 2022
1 parent ed2b205 commit f64062d
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
31 changes: 31 additions & 0 deletions docs/modules/Alternative.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Added in v2.0.0
- [Alternative4 (interface)](#alternative4-interface)
- [utils](#utils)
- [altAll](#altall)
- [getAlternativeMonoid](#getalternativemonoid)

---

Expand Down Expand Up @@ -137,3 +138,33 @@ export declare function altAll<F>(F: Alternative<F>): <A>(as: ReadonlyArray<HKT<
```

Added in v2.11.0

## getAlternativeMonoid

Lift a semigroup into a monoid alternative 'F', the inner values are concatenated using the provided `Semigroup`.

**Signature**

```ts
export declare function getAlternativeMonoid<F extends URIS4>(
F: Alternative4<F>
): <A, S, R, E>(S: Semigroup<A>) => Monoid<Kind4<F, S, R, E, A>>
export declare function getAlternativeMonoid<F extends URIS3>(
F: Alternative3<F>
): <A, R, E>(S: Semigroup<A>) => Monoid<Kind3<F, R, E, A>>
export declare function getAlternativeMonoid<F extends URIS3, E>(
F: Alternative3C<F, E>
): <A, R>(S: Semigroup<A>) => Monoid<Kind3<F, R, E, A>>
export declare function getAlternativeMonoid<F extends URIS2>(
F: Alternative2<F>
): <A, E>(S: Semigroup<A>) => Monoid<Kind2<F, E, A>>
export declare function getAlternativeMonoid<F extends URIS2, E>(
F: Alternative2C<F, E>
): <A>(S: Semigroup<A>) => Monoid<Kind2<F, E, A>>
export declare function getAlternativeMonoid<F extends URIS>(
F: Alternative1<F>
): <A>(S: Semigroup<A>) => Monoid<Kind<F, A>>
export declare function getAlternativeMonoid<F>(F: Alternative<F>): <A>(S: Semigroup<A>) => Monoid<HKT<F, A>>
```

Added in v2.13.0
36 changes: 36 additions & 0 deletions src/Alternative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -98,3 +101,36 @@ export function altAll<F>(F: Alternative<F>): <A>(as: ReadonlyArray<HKT<F, A>>)
export function altAll<F>(F: Alternative<F>): <A>(as: ReadonlyArray<HKT<F, A>>) => HKT<F, A> {
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 extends URIS4>(
F: Alternative4<F>
): <A, S, R, E>(S: Semigroup<A>) => Monoid<Kind4<F, S, R, E, A>>
export function getAlternativeMonoid<F extends URIS3>(
F: Alternative3<F>
): <A, R, E>(S: Semigroup<A>) => Monoid<Kind3<F, R, E, A>>
export function getAlternativeMonoid<F extends URIS3, E>(
F: Alternative3C<F, E>
): <A, R>(S: Semigroup<A>) => Monoid<Kind3<F, R, E, A>>
export function getAlternativeMonoid<F extends URIS2>(
F: Alternative2<F>
): <A, E>(S: Semigroup<A>) => Monoid<Kind2<F, E, A>>
export function getAlternativeMonoid<F extends URIS2, E>(
F: Alternative2C<F, E>
): <A>(S: Semigroup<A>) => Monoid<Kind2<F, E, A>>
export function getAlternativeMonoid<F extends URIS>(F: Alternative1<F>): <A>(S: Semigroup<A>) => Monoid<Kind<F, A>>
export function getAlternativeMonoid<F>(F: Alternative<F>): <A>(S: Semigroup<A>) => Monoid<HKT<F, A>>
export function getAlternativeMonoid<F>(F: Alternative<F>): <A>(S: Semigroup<A>) => Monoid<HKT<F, A>> {
const f = getApplySemigroup(F)
return <A>(S: Semigroup<A>) => {
const SF = f(S)
return {
concat: (first: HKT<F, A>, second: HKT<F, A>) =>
F.alt(SF.concat(first, second), () => F.alt(first, () => second)),
empty: F.zero()
}
}
}
20 changes: 20 additions & 0 deletions test/Alternative.ts
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand All @@ -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<number>()))
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<string>())
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<string>())
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'))
})
})

0 comments on commit f64062d

Please sign in to comment.