di 0.1.0
Loading...
Searching...
No Matches
monad_concept.h
Go to the documentation of this file.
1#pragma once
2
7#include "di/meta/core.h"
8#include "di/types/void.h"
9#include "di/util/forward.h"
11
12namespace di::concepts {
13namespace detail {
14 template<typename T>
15 struct MonadBindId {
16 constexpr auto operator()(auto&& value) const -> T { return T(util::forward<decltype(value)>(value)); }
17 constexpr auto operator()() const -> T { return T(); }
18 };
19
20 template<typename M>
21 struct MonadValue {};
22
23 template<template<typename...> typename Monad, typename T, typename... Args>
24 struct MonadValue<Monad<T, Args...>> : meta::TypeConstant<T> {};
25
26 template<typename M>
27 struct MonadFmapId {
28 template<typename T>
29 requires(!concepts::LValueReference<T> || !concepts::LValueReference<meta::Type<MonadValue<M>>>)
30 constexpr auto operator()(T&& value) const {
31 return util::forward<T>(value);
32 }
33
34 constexpr auto operator()(auto& value) const
35 requires(concepts::LValueReference<meta::Type<MonadValue<M>>>)
36 {
37 return util::ref(value);
38 }
39
40 constexpr void operator()() const {}
41 };
42}
43
44template<typename T>
45concept MonadInstance = requires(T&& value) {
46 // fmap (Haskell >>)
47 {
48 function::monad::fmap(util::forward<T>(value), detail::MonadFmapId<meta::RemoveCVRef<T>> {})
50
51 // bind (Haskell >>=)
52 {
53 function::monad::bind(util::forward<T>(value), detail::MonadBindId<meta::RemoveCVRef<T>> {})
56
57template<template<typename...> typename T>
58concept Monad = MonadInstance<decltype(T { types::Void {} })>;
59}
Definition monad_concept.h:45
Definition monad_concept.h:58
Definition core.h:114
Definition any_storable.h:9
constexpr auto bind
Definition monad_bind.h:14
constexpr auto fmap
Definition monad_fmap.h:14
constexpr auto enable_monad
Definition monad_enable.h:18
constexpr auto value
Definition value.h:34
RemoveCV< RemoveReference< T > > RemoveCVRef
Definition core.h:74
constexpr auto in_place_type
Definition in_place_type.h:12
constexpr auto ref
Definition reference_wrapper.h:98
Definition void.h:6