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

Feature request: mapMaybe #366

Open
GregorySchwartz opened this issue Nov 5, 2019 · 8 comments
Open

Feature request: mapMaybe #366

GregorySchwartz opened this issue Nov 5, 2019 · 8 comments

Comments

@GregorySchwartz
Copy link

I find myself doing fromJust . filter isJust . fmap f, where f :: a -> Maybe b. Is it possible to have a mapMaybe-like function for this to avoid importing and using partial functions?

@Gabriella439
Copy link
Owner

@GregorySchwartz: What is the type signature that you expect for this utility?

@GregorySchwartz
Copy link
Author

(a -> Maybe b) -> Shell a -> Shell b. Or, preferably, have an instance of Shell that would accomplish the same task (and more through generalization).

@int-index
Copy link
Collaborator

int-index commented Nov 6, 2019

Does this do what you want?

filterShell :: (a -> Maybe b) -> Shell a -> Shell b
filterShell p s = s >>= select . p

@Gabriella439
Copy link
Owner

Gabriella439 commented Nov 6, 2019

It seems like this doesn't have to be turtle-specific. This utility could be generalized to any MonadPlus:

example :: MonadPlus m => (a -> Maybe b) -> m a -> m b
example f m = do
    a <- m

    case f a of
        Nothing -> mzero
        Just b  -> return b

I'm actually surprised that there's not already something like this in Control.Monad.

@miguel-negrao
Copy link

Wouldn't the more general function be the following ?

example2 :: MonadPlus m => m (Maybe a) -> m a
example2 m = do
    a <- m
    case a of
        Nothing -> mzero
        Just b  -> return b

Then example f m = example2 $ fmap f m

@GregorySchwartz
Copy link
Author

Yes, that would be perfect (although simplier than I thought it would be, which is always a good thing!).

@Gabriella439
Copy link
Owner

@GregorySchwartz: Could you try to see if this could be added to base? If they turn it down, though, then I can add it to turtle

@hseg
Copy link

hseg commented Sep 12, 2021

This exists as the mapMaybe method of Filterable in witherable.
It seems the WrappedFoldable instance is the one wanted here (perhaps via DerivingVia?):

mapMaybe :: (Foldable f, Alterative f) => (a -> Maybe b) -> f a -> f b
mapMaybe f =
    foldr (\x xs -> case p x of {Just a -> pure a <|> xs; _ -> xs}) empty

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

No branches or pull requests

5 participants