Added lift2 and Functor/Applicative/Monad implementations for Result#2
Added lift2 and Functor/Applicative/Monad implementations for Result#2aoprisan wants to merge 16 commits into
Conversation
|
The Copy trait works fine for things that implement it like numbers but will fail on things like String. Error types usually don't have the Copy restriction for their Trait. In fact Error itself is a trait you should use this as a restriction and then allow the user to choose what to return as an error! (Usually some type of enum or struct implementing it) |
|
Overall, I really like what you've done, thanks! But as mgattozi has said, I'm a bit hesitant to merge with Result errors needing the Copy trait. As soon as that is cleaned up a bit, I'll definitely merge this to master. mgattozi is right that Error is a trait, so perhaps you could require E: Error, instead of E: Copy, or I'm sure there are other fixes. Again, thanks! |
|
Thanks for your input. The reason why I added the Copy restrictions if the fact that I think I need a way to take the current error which I get by reference and pass it to the Err constructor which expect a parameter by value (passing the ownership). In case of the Ok(_) branch, we have the passed in function which takes a &B and returns a A. To exemplify in case of functor: match *self {
Ok(ref x) => Ok(f(x)),
Err(ref e) => Err(*e),
}Error doesn't seem to help here. I would have let the E type free of any constraints, but I don't see how to get a E from &E. |
|
Perhaps the From trait? I'm not really sure of the answer off the top of my On Tue, Sep 20, 2016, 13:33 Andrei Oprisan notifications@github.com wrote:
|
|
I apologize if I missed something obvious, but I can't see how From would help me. What I mean is that I get a reference to the error and I need its value to pass it to Err(_). |
|
I think I was wrong here. Try with the Error trait and see if that works. I think it should. |
|
I am afraid it doesn't, I have the same issue |
|
Without seeing all the code I can't really do much to help. You shouldn't have to use clone either. It's even more resource usage than copy and still too restrictive.. |
|
If you have time, have a look here: https://github.com/aoprisan/Kinder/blob/master/src/functor.rs#L32 . It's the same situation in case of Monad/Applicative. I can even paste it here, it's quite short: impl<A, B, E : Clone> Functor<A> for Result<B, E> {
fn fmap<F>(&self, f: F) -> Result<A, E>
where F: Fn(&B) -> A
{
match *self {
Ok(ref x) => Ok(f(x)),
Err(ref e) => Err(e.clone()),
}
}
}To me the above it kind of makes sense, I mean |
|
I want to revisit this issue. As it stands, it is necessary for E to implement Clone based on the type of |
|
Given that Either is a Functor I would expect Result to be the same. However, given the issues inherent with Clone I would say Profunctor is probably a better fit here if we need to get it to work properly. |
I had to restrict the error type (E) to implement Copy, I kind of rushed a bit but I didn't knew exactly how to do it otherwise (I started checking Rust relatively recently).