ptal / expected Goto Github PK
View Code? Open in Web Editor NEWWhat did you expect?
What did you expect?
The category expected_like has no sense. Either we found a better concept and replace it or we just don't use any concept and do the specialization for expected and optional specifically.
boost/expected/algorithms/value_or.hpp
contains a function that can be generalized to other monads, as it is the case of expected<T>
, optional<T>
and future<T>
.
The first question is in which namespace this function must be defined.
The second is if it is worth defining a default for classes that or forward the call to a member function value_or
.
Having the configuration macros on a specific file allows to share them between other files, e.g. expected/unexpected.hpp could need it.
value doesn't express correctly the fact that the value is optional. optional_value?
There are a lot of check if BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined but we don't provide an alternative yet. Maybe we should stick to C++ compilers for the time been. We will manage this when we will move to C++98 compilers.
// features
template <class M, class Traits = rebindable_traits_t<M> >
using value_type = typename Traits :: template value_type<M>;
template <class M, class U, class Traits = rebindable_traits_t<M > >
using rebind = typename Traits :: template rebind<M, U>;
boost/expected/algorithms/catch_unexpected.hpp
contains a function that can be generalized to all the monad_error that store an exception_ptr
, as it is the case of expected<exception_ptr,T>
and future<T>
.
An alternative is to define this function for the error themselves, but then the user must first get the error and then do the catch_exception
.
Expected can be viewed as interfacing between a monadic code and an exception-throwing code. It could be convenient to have an adaptor that catch all the exception thrown and transform then on a expected <exception_ptr, T>
.
This adaptor could be used with fmap, mbind and then method.
e.mbind(catch_all(f));
Currently the value_traits forward all the operation fro the default category, that is the type itself. As a concept contains semantic constraints in addition of the syntactic ones, it would be better if the model designer states explicitly that the forward is correct way to map the type.
So I purpose to add a forward category and replace the default with this category.
template <class T>
struct value_traits : std::false_type {} ; // SFINAE friendly
template <class T>
struct value_traits<category::forward> : std::true_type // SFINAE friendly
{
template <class M>
static constexpr bool has_value(M&& m)
{ return m.has_value();}
template <class M>
static constexpr auto deref(M&& m) -> decltype(m.deref())
{ return m.deref();};
template <class M>
static constexpr auto get_value(M&& m) -> decltype(m.value())
{ return m.value(); };
};
boost::expected<int> fun() {
return boost::make_expected_from_error<int>(std::runtime_error("Test Error"));
}
int main(int argc, char* argv[]) {
fun();
}
As the above code example runs without producing any error. This shows that it's still possible to completely ignore any error conditions. http://stackoverflow.com/questions/14923346/how-would-you-use-alexandrescus-expectedt-with-void-functions addresses this.
Destructor of expected
could have an assert check that triggers if the return status has been completely ignored.
It provides make_exception, has_exception and catch_exception.
Expected can be viewed as interfacing between a monadic code and an exception-throwing code. It could be convenient to call a trait method when an exception is thrown inside fmap/mbind or then method. The default trait method would rethrow if the contained error type is not an exception_ptr.
Another possibility is to have different overload for the two possibilities, what do you think?
template< class M >
BOOST_CONSTEXPR bool have_value( M&& m )
{
return has_value(std::forward<M>(m));
}
template< class M1, class ...Ms >
BOOST_CONSTEXPR bool have_value( M1&& m1, Ms&& ...ms )
{
return has_value(std::forward<M1>(m1)) && have_value( std::forward<Ms>(ms)... );
}
We need to implement generic function over both expected and optional to achieve this.
This function can be used as
auto e = expected<errc>::make(2);
The workarounds such as static_addressof, constexpr_move, constexpr_forward, constexpr_addressof should be moved to specific files in the detail expected/directory.
To conform with the file name.
I agree the name errored is not so good, but it is better to be coherent.
Wi will change it to a better name when we find it.
finally :: MonadCatch m => m a -> m b -> m a
Perform an action with a finalizer action that is run, even if an exception occurs.
https://hackage.haskell.org/package/base-4.7.0.0/docs/Control-Exception.html#v:finally
boost/expected/algorithms/has_unexpected.hpp
contains a function that can be generalized to all the monad_error that store an exception_ptr
, as it is the case of expected<exception_ptr,T>
and future<T>
.
An alternative is to define this function for the error themselves, but then the user must first get the error and then do the has_exception
.
The xxx_category and xxx_traits are currently on the xxx namespace. There is no way to get ride of the xxx_prefix and so maybe these classes could be moved outside of the namespapce xxx. Only the types and operations associated to xxx are needed on the xxx namespace to avoid ambiguity.
Haskell has a default implementation for this operation using mbind.
template <class M, class T, class U>
apply<M,U> operator>>(apply<M,T>&& m1, apply<M,U>&& m2)
{
return mbind(m1, [&](T& ) { return m2; });
}
The operator >> is used in other EDSL as sequencing operator.
Haskell uses operator $.
The same operator is used in Pure library.
std::future constructor unwrap implicitly. I don't remember why this was decided. Should expected behave the same way?
namespace category
{
struct pointer_like {};
}
template <>
struct value_traits<category::pointer_like> {
template <class M>
using type = typename M::value_type;
template <class M>
static constexpr bool has_value(M&& m) { return bool(m); };
template <class M>
static constexpr auto derreference(M&& m) -> decltype(*m) { return *m; };
};
boost/expected/algorithms/unwrap.hpp
contains a function that can be generalized to other monads, as it is the case of expected<T>
, optional<T>
and future<T>
.
The first question is in which namespace this function must be defined.
The second is if it is worth defining a default for monads that have only one argument or forward the call to a member function unwrap.
Currently
expected<string> e{unexpect, 1};
fails to compile as exception_ptr
is not constructible from int
If we want that this code is well formed, we need to make the expected_traits<E>::from_error
a variadic function.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.