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: Convenience constructor for Result #1627

Open
justin-yan opened this issue May 25, 2023 · 2 comments
Open

Feature Request: Convenience constructor for Result #1627

justin-yan opened this issue May 25, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@justin-yan
Copy link

justin-yan commented May 25, 2023

Hello! Apologies for filing as a "bug" but didn't see another issue type I could file as.

I was wondering if there was any appetite for an additional constructor on Result that would implement something akin to Scala's Try constructor (e.g. https://alvinalexander.com/scala/try-success-failure-example-reading-file/)

As a very primitive example, I often use a utility function that looks something like this:

def res_lift(lambda_function: Callable[[], T]) -> Result[T, Exception]:
    try:
        return Result.from_value(lambda_function())
    except Exception as e:
        return Result.from_failure(e)

So that I can do something like res_lift(lambda: something_that_might_error()) and easily get a ResultE out. This would kind of be like Maybe's .from_optional method (https://returns.readthedocs.io/en/latest/pages/maybe.html#maybe-container), except it would be for ResultE.

I'm not totally sure it's feasible to implement this in a way that's general for all Result Failure types (I recognize that Exception isn't the only Failure type that people use), but if there's interest, I'd be happy to try and put together a PR for this or collaborate however would be useful!

@justin-yan justin-yan added the bug Something isn't working label May 25, 2023
@sobolevn
Copy link
Member

https://github.com/dry-python/returns/blob/master/returns/result.py#L561 I think that this function does what you want, doesn't it?

@justin-yan
Copy link
Author

Thanks for taking a look!

You're totally right - I had looked at safe and didn't think it met my needs since I didn't want to decorate functions, but I forgot that I can just use it directly on lambdas. For example, I think I would need to do:

resulte = safe(lambda: 1)()

vs. something like

resulte = Result.lift(lambda: 1)

My general use case is that I often have to use IO libraries (e.g. an ORM) which haven't annotated their return types as ResultE, and so when I invoke those methods, I frequently need to "lift" the resulting value into Result space so that I can then work monadically.

It would be a small syntactic convenience to have such a method on the Result, and not need to add the extra invocation after wrapping with safe.

However, I think your point is very fair, and if you don't want to increase the surface area of your library for that (admittedly) small bit of convenience I'd totally understand. Thanks for taking a look!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

2 participants