mtomko
December 24, 2021, 10:18am
#1
I'm new to Rust, coming from a functional Scala background. I noticed in a few places in my code when dealing with Result
types that I'm calling map
and map_err
immediately after, when I want to return a Result
after applying the appropriate function (depending on whether the result is Ok
or `Err'). In Scala, we'd call this 'bimap'.
I don't see such a function defined on Result
- .map_or_else
is close, but it wants to return a non-result type. Can I define something like it?
I tried to sketch out something like it:
use std::ops::FnOnce;
trait ResultOps<T, E> {
fn bi_map<U, A, B, D: FnOnce(E) -> B, F: FnOnce(T) -> A>(self, l: D, r: F) -> Result<A, B>;
}
impl ResultOps<T, E> for Result<T, E> {
fn bi_map<U, A, B, D: FnOnce(E) -> B, F: FnOnce(T) -> A>(self, l: D, r: F) -> Result<A, B> {
match self {
Ok(t) => Ok(r(t)),
Err(e) => Err(l(e)),
}
}
}
Am I close? The compiler is happy with my trait, but can't find T
or E
in my implementation:
cannot find type `T` in this scope
not found in this scope
sigmaSd
December 24, 2021, 10:25am
#2
Very close!
You need to tell rust that you're going to use a generic type:
impl<T,E> ResultOps<T, E> for Result<T, E>
Also the U
generic looks to be unneeded.
1 Like
mtomko
December 24, 2021, 10:35am
#3
You're right, thanks! This seems to compile and it works in my code:
use std::ops::FnOnce;
pub trait ResultOps<T, E> {
fn bi_map<A, B, D: FnOnce(E) -> B, F: FnOnce(T) -> A>(self, l: D, r: F) -> Result<A, B>;
}
impl<T, E> ResultOps<T, E> for Result<T, E> {
fn bi_map<A, B, D: FnOnce(E) -> B, F: FnOnce(T) -> A>(self, l: D, r: F) -> Result<A, B> {
match self {
Ok(t) => Ok(r(t)),
Err(e) => Err(l(e)),
}
}
}
As for why it's like this: It's possible to make a non-generic impl
block. So you can do
impl ResultOps<PathBuf, String> for Result<PathBuf, String> {
at which point you don't want those to be the names of generic parameters.
(Now, obviously you don't want that in this particular case, but that's why the declaration is needed for the generic types.)
1 Like
system
closed
March 24, 2022, 11:44am
#5
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.