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

New extra combinator: generalised 'readMaybe' #161

Open
josephcsible opened this issue May 9, 2019 · 3 comments
Open

New extra combinator: generalised 'readMaybe' #161

josephcsible opened this issue May 9, 2019 · 3 comments
Labels
enhancement New feature or request new Bring something new into library (add function or type or interface) question Further information is requested reexport Reexport something new

Comments

@josephcsible
Copy link
Contributor

readMaybe is implemented like this:

readMaybe :: Read a => String -> Maybe a
readMaybe s = case readEither s of
                Left _  -> Nothing
                Right a -> Just a

There's a lot of other types that it would be useful to generalize this to. Here's two ideas I've had:

readFail :: (MonadFail f, Read a) => String -> f a
readFail s = case readEither s of
                Left e  -> fail e
                Right a -> return a
readAlt :: (Alternative f, Read a) => String -> f a
readAlt s = case readEither s of
                Left _  -> empty
                Right a -> pure a

Both of those are the same as readMaybe when f ~ Maybe. The first is useful for custom error monads to preserve whether the problem was "no parse" or "ambiguous parse". The second is useful for MaybeT and lots of other things that have some sort of failure state.

@chshersh chshersh changed the title Generalize readMaybe Generalize readMaybe over return type May 10, 2019
@chshersh chshersh added question Further information is requested enhancement New feature or request labels May 10, 2019
@chshersh
Copy link
Contributor

chshersh commented May 10, 2019

@josephcsible Thanks for the suggestion! I can see how more polymorphic readMaybe can be useful. I would prefer not to change the type of readMaybe to have fewer surprises for the relude users.

I think that both readFail and readAlt can be useful. However, it's not clear which one to choose. So instead of hardcoding implementation of parsing function, I propose to introduce more useful combinators that deal with Either a b and Maybe a. Hoogling interesting types I see the room for the following functions:

-- Either
rightZ :: (MonadPlus m) => Either e a -> m a
hush :: Alternative m => Either e a -> m a
liftEither :: MonadError e m => Either e a -> m a
eitherToError :: MonadError e m => Either e a -> m a

-- Maybe
hoistMaybe :: MonadPlus m => Maybe a -> m a
maybeToAlternative :: Alternative f => Maybe a -> f a
note :: MonadError e m => e -> Maybe a -> m a

These functions come from popular and common packages like protolude, mtl and errors, so they could be an excellent addition. We only need to decide which ones to add and under what names. Currently, I can say without a doubt that reexporting liftEither from mtl can be done.

@chshersh chshersh added new Bring something new into library (add function or type or interface) reexport Reexport something new labels May 10, 2019
@chshersh chshersh changed the title Generalize readMaybe over return type New extra combinator: generalised 'readMaybe' May 6, 2020
@chshersh
Copy link
Contributor

chshersh commented May 6, 2020

In relude we want to be more beginner-friendly and have fewer surprises for users. Changing the type of one of the most common functions would be against our goals. I personally never needed a more polymorphic readMaybe, so I assume that the benefits of this change are low, but the confusion caused by using more abstractions can be noticeable. Moreover, there're multiple competitive choices without a clear winner. I don't think the community has settled on some of the options.

However, such combinator still can be added to some Extra. module. But I would like to avoid populating relude with multiple rarely-used functions, so let's gather more opinions on this issue first before introducing something, we are going to suggest and going to maintain forever.

@josephcsible
Copy link
Contributor Author

To clarify, I definitely don't want a new function called readMaybe with a different type. I definitely agree if we add one, it should have a different name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request new Bring something new into library (add function or type or interface) question Further information is requested reexport Reexport something new
Projects
None yet
Development

No branches or pull requests

2 participants