Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative: add getAlternativeMonoid #1717

Merged
merged 1 commit into from
Sep 9, 2022

Conversation

willheslam
Copy link
Contributor

This provides a way to lift a semigroup into a monoid via an alternative...
think of it like a generalised version of Option's getMonoid, except it applies to any Alternative.

It also means any module without a specialised getMonoid function like TaskOption and IOOption also have a way to produce an amalgamation.

Hopefully this is useful and not a duplication of functionality.
Alternatively, should all Alternative-capable modules expose a getMonoid function?

I did debate adding a way to get an Alternative Semigroup from a Semigroup (and Alternative Monoid from a Monoid) but I realised this had the biggest bang for buck in utilising the capabilities of the underlying Alternative.
I am pretty sure the order of () => F.alt(first, () => second)) is irrelevant given it's a Semigroup.

(If the tests are redundant I'd be happy to rewrite them as showing identical behaviour to Option's getMonoid function.)

@gcanti gcanti added this to the 2.13 milestone Sep 3, 2022
@gcanti
Copy link
Owner

gcanti commented Sep 7, 2022

@willheslam not sure why the CI is failing, the log is no longer available

src/Alternative.ts Outdated Show resolved Hide resolved
@willheslam
Copy link
Contributor Author

@willheslam not sure why the CI is failing, the log is no longer available

I don't remember either, but it's passing now. Thanks for reviewing this!

@gcanti gcanti merged commit f64062d into gcanti:master Sep 9, 2022
@gcanti
Copy link
Owner

gcanti commented Sep 9, 2022

Thank you @willheslam

@CarstenLeue
Copy link

Hi @willheslam, not sure if you see this on a merged PR but I have the following question:

in the implementation

return {
      concat: (first: HKT<F, A>, second: HKT<F, A>) =>
        F.alt(SF.concat(first, second), () => F.alt(first, () => second)),
      empty: F.zero()
    }

both first and second are being used twice and might also be evaluated twice, e.g. if SF.concat(first, second) fails and the alternative gets pulled in, first will be evaluated again.
If this is an effectful operation, e.g. a TaskEither this task would be triggered twice. This might be a performance concern but also might lead to unexpected results for side effects.

Is there a particular conceptual reason to evaluate the parameters twice? Do you see any potential issue with this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants