
On 29 Jun 2015 at 17:54, Vicente J. Botet Escriba wrote:
Niall, I don't see why do you need to define a concrete monad class that is used to define other monadic types. The implementation of each specific monadic type has its own trade-offs.
We can provide monadic operations for optional/expected/future/....
Why do you need to have a concrete monad class? What is the added value?
Let me flip the question to you. Why does it matter how the monadic types are implemented? All the user needs to care about is that monad<T>, result<T>, option<T>, future<T>, future_result<T> and future_option<T> behave according to strict and sensible rules which make sense to program against. You could of course implement them separately. I chose not to, but that's an internal implementation detail. Each correctly SFINAE's out those functionalities they don't provide and/or provides a static_assert when you try doing something you can't. If you're really asking why are they all so similar, I'd also flip the question: "why is experimental::optional<T> not the same pattern as future<T>?" Both transport a T, so why aren't they the same? There are many advantages and very few costs if they were. I especially like that I can use the same mental model for both, both have identical APIs where that makes sense, and both work the same way in my head. Both are also each absolutely minimum impact on build and runtime costs, I have a suite of unit tests verifying that per commit. BTW there is absolutely nothing ruling out a later monad<T,E>. I deliberately left that open for the future, all the existing design an API assumes an implict monad<T, E=variant<error_code, exception_ptr>>. Any code written against the current design would work with a recompile with a later monad<T, E>. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/