LeechCraft 0.6.70-16373-g319c272718
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
monad.h
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#pragma once
10
11#include <optional>
12#include "typelist.h"
13#include "applicative.h"
14#include "either.h"
15
16namespace LC
17{
18namespace Util
19{
20 template<typename T>
22
23 template<template<typename...> class Monad, typename... Args, typename V>
24 auto Return (const V& v)
25 {
26 return Pure<Monad, Args...> (v);
27 }
28
29 template<typename MV, typename F>
31
32 namespace detail
33 {
34 template<template<typename...> class Monad, typename... Args1, typename... Args2>
35 constexpr bool IsCompatibleMonadImpl (const Monad<Args1...>*, const Monad<Args2...>*, int)
36 {
37 return std::is_same<
38 decltype (Init (Typelist<Args1...> {})),
39 decltype (Init (Typelist<Args2...> {}))
40 >::value;
41 }
42
43 template<typename T1, typename T2>
44 constexpr bool IsCompatibleMonadImpl (const T1*, const T2*, ...)
45 {
46 return false;
47 }
48
49 template<typename T>
50 constexpr T* declptr () noexcept
51 {
52 return nullptr;
53 }
54
55 template<typename T1, typename T2>
56 constexpr bool IsCompatibleMonad ()
57 {
59 }
60 }
61
62 template<typename MV, typename F>
63 BindResult_t<MV, F> Bind (const MV& value, const F& f)
64 {
66 "Incompatible function return type");
67 return InstanceMonad<MV>::Bind (value, f);
68 }
69
70 template<typename MV, typename F>
71 auto operator>> (const MV& value, const F& f) -> decltype (Bind (value, f))
72 {
73 return Bind (value, f);
74 }
75
76 template<typename MV>
77 auto Do (const MV& value)
78 {
79 return value;
80 }
81
82 template<typename MV, typename FHead, typename... FArgs>
83 auto Do (const MV& value, const FHead& fHead, const FArgs&... fArgs)
84 {
85 return Do (Bind (value, fHead), fArgs...);
86 }
87
88 // Implementations
89 template<typename T>
90 struct InstanceMonad<std::optional<T>>
91 {
92 template<typename F>
93 using BindResult_t = std::result_of_t<F (T)>;
94
95 template<typename F>
96 static BindResult_t<F> Bind (const std::optional<T>& value, const F& f)
97 {
98 if (!value)
99 return {};
100
101 return f (*value);
102 }
103 };
104
105 template<typename L, typename R>
106 struct InstanceMonad<Either<L, R>>
107 {
108 template<typename F>
109 using BindResult_t = std::result_of_t<F (R)>;
110
111 template<typename F>
112 static BindResult_t<F> Bind (const Either<L, R>& value, const F& f)
113 {
114 using R_t = BindResult_t<F>;
115
116 if (value.IsLeft ())
117 return R_t::Left (value.GetLeft ());
118
119 return f (value.GetRight ());
120 }
121 };
122}
123}
const R & GetRight() const
Definition either.h:72
bool IsLeft() const
Definition either.h:55
const L & GetLeft() const
Definition either.h:65
constexpr T * declptr() noexcept
Definition monad.h:50
constexpr bool IsCompatibleMonad()
Definition monad.h:56
constexpr bool IsCompatibleMonadImpl(const Monad< Args1... > *, const Monad< Args2... > *, int)
Definition monad.h:35
constexpr auto Init(List< Args... >)
Definition typelist.h:89
auto Do(const MV &value)
Definition monad.h:77
auto operator>>(const MV &value, const F &f) -> decltype(Bind(value, f))
Definition monad.h:71
auto Return(const V &v)
Definition monad.h:24
BindResult_t< MV, F > Bind(const MV &value, const F &f)
Definition monad.h:63
auto Pure(const T &v)
Definition applicative.h:25
typename InstanceMonad< MV >::template BindResult_t< F > BindResult_t
Definition monad.h:30
Definition constants.h:15
STL namespace.
static BindResult_t< F > Bind(const Either< L, R > &value, const F &f)
Definition monad.h:112
std::result_of_t< F(R)> BindResult_t
Definition monad.h:109
std::result_of_t< F(T)> BindResult_t
Definition monad.h:93
static BindResult_t< F > Bind(const std::optional< T > &value, const F &f)
Definition monad.h:96