-
Notifications
You must be signed in to change notification settings - Fork 135
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
Add monadic bind operators, >= and > #87
base: master
Are you sure you want to change the base?
Conversation
I could use some help with this CI build failure. I've been able to duplicate it locally on gcc-10.3.0 by using I imagine this behaviour has something to do with some of the deprecation surrounding I've also tried using Any help or tips would be greatly appreciated. I'm happy to provide any other information you might need. |
Hello, In the more general term, you operators probably don't need you to specify the return type at all, auto alone would do just fine. The issue here is that your code is not correct and is only valid when your functors don't change the nested type. So to fix both at once, you should probably just use the and_then member function and everything will work. That being said, two issues I see coming:
In any case, you should write some unit tests to check that everything works in all cases. |
@julienlopez thanks for your thoughts and your help. I'll take a look at the fixes as you've suggested. As you pointed out, the As far as Whereas I thought maybe naming it |
Yes, map is different from your > operator. There is nothing like >> in this lib, and it could be a nice addition, even if I rarely ended up in this case so far. To my (very limited) understanding of haskell >>= can bind both functions in the form (A -> B) and (A -> m B), right? In this lib, there is nothing to do both, so there are two function, map (taking a functor like A -> B) and and_then (taking a functor like A -> m B). As it is, using map on a functor like A -> m B would result in an m m B in expected (ex<ex<B, E>, E> in a more c++ / template form). Since I don't really see the point of having such a construct, having an operator handling both and calling the right function between map or and_then would be a nice addition to this lib imo, but it's gonna be trickier to implement, espcially if c++11 compatibility is to be kept. Is this what you intend to do? |
Signed-off-by: Wolfgang E. Sanyer <[email protected]>
8b2a597
to
c8f0a48
Compare
Yes I agree this would be nice: that is why I am trying to add it 😀
No this is wrong, in haskell there are very distinct Briefly, here are the different function signatures: Control.Monad (>>=) :: forall a b . Monad m => m a -> (a -> m b) -> m b
Control.Monad fmap :: Functor f => (a -> b) -> f a -> f b So, whereas Dang I guess that wasn't very brief or illuminating :-P The difference between There!
So perhaps I'll start with some haskell code: do
x <- someMonadicOp
return someOpThatNeedsX x The do-notation is nice, but is simply syntactic sugar for someMonadicOp >>= someOpThatNeedsX Sometimes, you need something like this though: do
someMonadicOpThatChecksSomething
someOtherMonadicOp
x <- someMonadicOp
return someOpThatNeedsX x Again, if we unwrap the nice do-notation: someMonadicOpThatChecksSomething >> someOtherMonadicOp >> someMonadicOp >>= someOpThatNeedsX Just to be clear, this could also be written as: someMonadicOpThatChecksSomething >>
\_ -> someOtherMonadicOp >>
\_ -> someMonadicOp >>=
\x -> someOpThatNeedsX x Where I find this sort of programming style extremely helpful: notice here for example. I want to check that both the Anyway, I think my comment has drawled on long enough...please take a look at my latest commit and let me know your thoughts, I think I might be getting close. |
This is opt-in, using the EXPECTED_BIND_OPERATORS cmake definition Signed-off-by: Wolfgang E. Sanyer <[email protected]>
c8f0a48
to
7c1afd3
Compare
Switching this back to draft - it turns out that my In other words: I might update my PR to improve the documentation to make this clear. I still think the bind operators could be useful. Finally, I think it could be helpful to update // current implementation of and_then
auto ret =
someFunc
.and_then(std::bind(f, x, y, z)) // let's say: tl::expected<...> f(int, int, int, tl::expected<...>
.and_then(std::bind(g, x, y, z)) // in this case tl::expecte<...> g(int, int, int) Could be simplified to: auto ret =
someFunc
.and_then(f, x, y, z)
.and_then(g, x, y, z) I'm toying around with it now do see if I can add this functionality |
These are equivalent to the haskell
>>=
and>>
operators respectively. Theycan be used as follows:
Signed-off-by: Wolfgang E. Sanyer [email protected]