18 using left_t = single<T, std::false_type>;
21 using right_t = single<T, std::true_type>;
24 constexpr left_t<std::unwrap_ref_decay_t<T>> make_left(T&& t) {
25 return std::forward<T>(t);
29 constexpr right_t<std::unwrap_ref_decay_t<T>> make_right(T&& t) {
30 return std::forward<T>(t);
34 template <
class T,
class U>
41 template <
class T,
class U>
48 template <
class T,
class U>
54 template <
class T1,
class T2>
58 template <
class F, is_either E>
59 constexpr auto operator()(F&& f, E&& e)
const
61 std::unwrap_ref_decay_t<std::invoke_result_t<F, alternative_value_t<1, E>>>> {
63 return std::get<0>(std::forward<E>(e));
65 return make_right(std::invoke(std::forward<F>(f), *std::get<1>(std::forward<E>(e))));
70 static constexpr fmap_op
fmap{};
77 template <
class T1,
class T2>
81 template <is_either E,
class F>
82 constexpr auto operator()(E&& e, F&& f)
const
83 ->
decltype(std::invoke(std::forward<F>(f), *std::get<1>(std::forward<E>(e)))) {
85 return std::get<0>(std::forward<E>(e));
87 return std::invoke(std::forward<F>(f), *std::get<1>(std::forward<E>(e)));
92 static constexpr bind_op
bind{};
99 template <
class T1,
class T2>
104 constexpr auto operator()(U&& u)
const
106 return make_right(std::forward<U>(u));
111 struct seq_apply_op {
112 template <is_either E1, is_either E2>
113 constexpr auto operator()(E1&& e1, E2&& e2)
const
121 if (e1.index() == 0) {
122 return std::get<0>(std::forward<E1>(e1));
124 return mpc::fmap(*std::get<1>(std::forward<E1>(e1)), std::forward<E2>(e2));
129 static constexpr pure_op
pure{};
130 static constexpr seq_apply_op
seq_apply{};
typename std::variant_alternative_t< Idx, std::remove_cvref_t< Variant > >::value_type alternative_value_t
alternative_value_t
Definition: alternative_value_t.hpp:13
std::variant< left_t< T >, right_t< U > > either
data Either a b = Left a | Right b
Definition: either.hpp:35
constexpr partial< detail::liftA2_op > liftA2
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
Definition: applicative.hpp:173
constexpr auto discard2nd
discard2nd :: f a -> f b -> f a
Definition: applicative.hpp:182
constexpr partial< detail::fmap_op > fmap
fmap :: (a -> b) -> f a -> f b
Definition: applicative.hpp:161
constexpr partial< detail::bind_op > bind
bind :: forall a b. m a -> (a -> m b) -> m b
Definition: monad.hpp:45
constexpr partial< detail::replace2nd_op > replace2nd
replace2nd :: a -> f b -> f a
Definition: functor.hpp:53
constexpr partial< detail::seq_apply_op > seq_apply
seq_apply :: f (a -> b) -> f a -> f b
Definition: applicative.hpp:99
constexpr partial< detail::pure_op< F > > pure
pure :: a -> f a
Definition: applicative.hpp:96
constexpr auto replace2nd
replace2nd :: a -> f b -> f a
Definition: functor.hpp:65
constexpr partial< detail::discard1st_op > discard1st
discard1st :: f a -> f b -> f b
Definition: monad.hpp:109
class Functor f => Applicative f where
Definition: applicative.hpp:18
Definition: either.hpp:39
class Functor f where
Definition: functor.hpp:14
Definition: holding.hpp:7
class Applicative m => Monad m where
Definition: monad.hpp:15
A class that holds a single value.
Definition: single.hpp:15