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

Rationale behind Result::{map_err,map} func sig? #32

Open
Pegasust opened this issue Mar 15, 2023 · 0 comments
Open

Rationale behind Result::{map_err,map} func sig? #32

Pegasust opened this issue Mar 15, 2023 · 0 comments

Comments

@Pegasust
Copy link

Love the python module! It makes my small codebase extremely simple and makes error handling much more sane!

What?

Though, I'm unable to get around the fact that Result.map_err has the effective func sig of:

map_err :: Result<T, E> -> (E -> F) -> Result<T, E | F>

The original return type is Result<T, E> | Result<T, F>.

I think it should just be Result<T, F>

Why?

My opinion, if it's Result::Ok, then map_err is no-op; the data (under user's scope) is only T, and we should be able to cast:
return typing.cast(Result[T, F], self)

If it's Result::Err, wouldn't it forcefully go through fn and become F?

In the end, both branches yields Result<T, F>, there is no possibility of E for error type.

The same argument applies for Result::map as well.

Why is this relevant?

I'm trying to implement an equivalence of ? operator in Rust:

E = TypeVar('E', bound=BaseException)
T = TypeVar('T')
def err_into(result: Result[T, E]) -> Result[T, str]:
    # TYPE ERR: E@result is invariant: E@err_into cannot be assigned to `str`
    return result.map_err(lambda e: str(e))
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

1 participant