mpc
Haskell-like feature supports in C++
alternative.hpp
Go to the documentation of this file.
1
2#pragma once
5
6// clang-format off
7
8namespace mpc {
9 // alternative
10 // https://hackage.haskell.org/package/base-4.16.0.0/docs/Control-Applicative.html#t:Alternative
11
13 template <class>
15
16 namespace detail {
18 template <class F>
19 concept has_alternative_traits_empty = requires {
20 alternative_traits<std::remove_cvref_t<F>>::empty();
21 };
22
24 template <class F>
25 concept has_alternative_traits_combine = requires {
26 alternative_traits<std::remove_cvref_t<F>>::combine;
27 };
28 } // namespace detail
29
31 template <class F>
34
36 template <class F>
38
39 // Methods required for the class definition.
40
41 namespace detail {
46 template <class F>
47 struct empty_op {
48 constexpr auto operator*() const noexcept(
52 };
53
58 struct combine_op {
59 template <class Fa, class Fb>
60 requires std::same_as<std::remove_cvref_t<Fa>, std::remove_cvref_t<Fb>>
61 constexpr auto operator()(Fa&& fa, Fb&& fb) const noexcept(
62 noexcept( alternative_traits<std::remove_cvref_t<Fa>>::combine(std::forward<Fa>(fa), std::forward<Fb>(fb))))
63 -> decltype(alternative_traits<std::remove_cvref_t<Fa>>::combine(std::forward<Fa>(fa), std::forward<Fb>(fb)))
64 { return alternative_traits<std::remove_cvref_t<Fa>>::combine(std::forward<Fa>(fa), std::forward<Fb>(fb)); }
65 };
66 } // namespace detail
67
68 inline namespace cpo {
70 template <class F>
71 inline constexpr detail::empty_op<F> empty{};
72
75 } // namespace cpo
76
77 // Grobal methods
78
79 namespace operators::alternatives {
81 template <class Fa, class Fb>
82 requires std::same_as<std::remove_cvref_t<Fa>, std::remove_cvref_t<Fb>>
83 inline constexpr auto operator||(Fa&& fa, Fb&& fb)
84 noexcept(noexcept(mpc::combine(std::forward<Fa>(fa), std::forward<Fb>(fb))))
85 -> decltype( mpc::combine(std::forward<Fa>(fa), std::forward<Fb>(fb))) {
86 return mpc::combine(std::forward<Fa>(fa), std::forward<Fb>(fb));
87 }
88 } // namespace operators::alternatives
89} // namespace mpc
90
91// clang-format on
constexpr auto operator||(Fa &&fa, Fb &&fb) noexcept(noexcept(mpc::combine(std::forward< Fa >(fa), std::forward< Fb >(fb)))) -> decltype(mpc::combine(std::forward< Fa >(fa), std::forward< Fb >(fb)))
combine :: f a -> f a -> f a
Definition: alternative.hpp:83
alternative_traits_specialized
Definition: alternative.hpp:32
Requires applicative and empty and combine is valid in alternative_traits .
Definition: alternative.hpp:37
Requires functor and pure, seq_apply, liftA2, discard2nd and discard1st is valid in applicative_trait...
Definition: applicative.hpp:32
has_alternative_traits_combine
Definition: alternative.hpp:25
has_alternative_traits_empty
Definition: alternative.hpp:19
constexpr detail::empty_op< F > empty
empty :: f a
Definition: alternative.hpp:71
constexpr partial< detail::combine_op > combine
combine :: f a -> f a -> f a
Definition: alternative.hpp:74
class Applicative f => Alternative f where
Definition: alternative.hpp:14
combine :: f a -> f a -> f a
Definition: alternative.hpp:58
empty :: f a
Definition: alternative.hpp:47
Implements a perfect-forwarding call wrapper.
Definition: partial.hpp:63