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

orElse for Error Type Transformation #95

Closed
Hosshii opened this issue Feb 24, 2024 · 2 comments
Closed

orElse for Error Type Transformation #95

Hosshii opened this issue Feb 24, 2024 · 2 comments

Comments

@Hosshii
Copy link

Hosshii commented Feb 24, 2024

Hello.

Currently, Result.orElse has the following signature:

<V, E> Result<V, E>.orElse(transform: (E) -> Result<V, E>): Result<V, E>

However, it does not allow for changing the type of the error. Rust's or_else can change it, so how about modify it to align with that capability?

<T, E, F> Result<T, E>.orElse(transform: (E) -> Result<T, F>): Result<T, F>

thanks!

@michaelbull
Copy link
Owner

This seems like a good idea and would be a backwards-compatible change. I'm wondering if there was a reason I didn't do it like this originally - maybe Rust's reference impl wasn't always like this?

Either way seems like a good change - are there any other callsites like this that would benefit from the increased signature mapping capability?

@Hosshii
Copy link
Author

Hosshii commented Mar 2, 2024

I wonder too, but the Rust implementation does not seem to have changed since at least version 1.0.
https://doc.rust-lang.org/1.0.0/std/result/enum.Result.html#method.or_else
In Rust, unlike Kotlin, the positions of type parameters are more separated, which might be the reason for some differences. In Kotlin, all type parameters appear on one line.

<V, E, U> Result<V, E>.map(transform: (V) -> U): Result<U, E>

For Rust:

impl Result<V, E> {
    // many
    // other
    // methods
    // ...
    pub fn map<U>(self, op: fn(V) -> U) -> Result<U, E>
}

Here, T and E are declared at the block level (I replaced F for simplicity in the example, but please disregard this substitution).
https://doc.rust-lang.org/std/result/enum.Result.html#method.map

I have only been able to find out about the Rust and Haskell on wiki, but besides or_else, Result.and and Result.or can also be modified similarly to Rust's and and or. It is currently as follows:

<V, E> Result<V, E>.and(result: Result<V, E>): Result<V, E>

I think the type of the success value in the argument can be made arbitrary.

<V, E, U> Result<V, E>.and(result: Result<U, E>): Result<U, E>

Similarly, Result.or

<V, E> Result<V, E>.or(result: Result<V, E>): Result<V, E>

I believe the error type can also be made arbitrary.

<V, E, F> Result<V, E>.or(result: Result<V, F>): Result<V, F>

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

2 participants