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