On 29 Jun 2015 at 10:05, Andrzej Krzemienski wrote:
Empty => False (future/monad/result/option) Errored/Excepted => Indeterminate (future/monad/result) Value => True (future/monad/result/option)
The meaning of empty in optional/option and future is not the same. For the fist is a valid state, for the second is an invalid state.
If "empty" means something different in the case of three-type "result", perhaps it deserves a different name?
In my synchronous monad, empty is always an invalid state, just as with future. States T/errored/excepted are always valid states.
In addition asynchronous types have an additional state not-ready, e.g. future can be invalid, not-ready, exceptional or valued.
So it looks like you have two sets of error codes: 1. The one represented by E in result
2. A set of error conditions inherent to asynchronous state processing: "invalid", "not ready" (maybe also "already retrieved").
You have nailed another design tradeoff I made on the head. Right now if lightweight future experiences an error condition, it makes the future valid in order to set the state to that error condition which is of type future_errc. monad behaves identically, as it maps future as closely as possible, except it uses type monad_errc (which is a subset of future_errc). This, as you correctly observe means that one cannot disambiguate between a user who tries to transport a monad_errc with monad<T> and a monad<T> which set itself to an errored state due to some problem. As the docs say, "don't use monad<T> to transport a monad_errc nor a future_errc. Misoperation is likely". Note also that lightweight monad<T> and future<T> both explicitly static_assert prevent you from using a T which is an error_type or an exception_type. In other words, monadstd::error_code or monadstd::exception_ptr will fail to compile. In the docs I suggest that if you really need to transport those, wrap them in a wrapper type. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/