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

maybe, either: define "fantasy-land/concat" conditionally #359

Merged
merged 1 commit into from
Apr 4, 2017

Conversation

davidchambers
Copy link
Member

@davidchambers davidchambers commented Mar 5, 2017

Closes #346

Before:

S.concat(S.Just(1), S.Just(1));
// ! TypeError: Semigroup.methods.concat(...) is not a function

After:

S.concat(S.Just(1), S.Just(1));
// ! TypeError: Type-class constraint violation
//
//   concat :: Semigroup a => a -> a -> a
//             ^^^^^^^^^^^    ^
//                            1
//
//   1)  Just(1) :: Maybe Number, Maybe FiniteNumber, Maybe NonZeroFiniteNumber, Maybe Integer, Maybe ValidNumber
//
//   ‘concat’ requires ‘a’ to satisfy the Semigroup type-class constraint; the value at position 1 does not.

Losing the ability to filter(odd, Just(4)) is a real shame. This happens because Just(4) does not satisfy the requirements of Monoid as it does not satisfy the requirements of Semigroup.

It seems we need mfilter. Fantasy Land does not yet specify MonadPlus. We could define mfilter and hard-code support for the Maybe type, while also pushing to have MonadPlus added to Fantasy Land. With luck we would later be able to move the implementation from mfilter to Maybe#fantasy-land/mplus. Is this reasonable?

@safareli
Copy link
Member

safareli commented Mar 6, 2017

MonadPlus is just Monad + Alternative with some extra laws(on which there still is debate), and even if it would be added to FL one couldn't distinguish between some (Apply m, Chain m, Plus m) => m and (MonadPlus m) => m as it's not adding any new methods.

so you can write:

// :: (Alternative m, Monad m) => (a -> Boolean, m a) -> m a
// -- or:
// :: (Plus m, Chain m, Apply m) => (a -> Boolean, m a) -> m a
// --  but I think first one is much better
const mfilter = (p,ma) => {
  const T = ma.constructor
  return ma.chain(a => p(a) ? T.of(a) : T.zero()
}

@davidchambers
Copy link
Member Author

Terrific suggestion, @safareli! The Sanctuary projects—sanctuary-type-classes in particular—would not be where they are today without your involvement. Thank you!

I just opened sanctuary-js/sanctuary-type-classes#37. Have a look. :)

@safareli
Copy link
Member

safareli commented Mar 6, 2017

@davidchambers Welcome! ;)

@davidchambers davidchambers force-pushed the davidchambers/concat branch from 5ab71c1 to 6ecc1e6 Compare April 3, 2017 01:25
@davidchambers
Copy link
Member Author

I rebased on #370 to confirm that values of type Maybe a will remain compatible with filterM. :)

@davidchambers davidchambers force-pushed the davidchambers/concat branch from 6ecc1e6 to d971077 Compare April 4, 2017 12:45
@Avaq
Copy link
Member

Avaq commented Apr 4, 2017

LGTM - Seems tests experience IE10 iFrame resource error again. Probably some race condition.

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