Boost.Hana: Monad

| Boost.Hana 1.7.1 Your standard library for metaprogramming |

Variables
Monad
Concepts

## Description

The `Monad` concept represents `Applicative`s with the ability to flatten nested levels of structure.

Historically, Monads are a construction coming from category theory, an abstract branch of mathematics. The functional programming community eventually discovered how Monads could be used to formalize several useful things like side effects, which led to the wide adoption of Monads in that community. However, even in a multi-paradigm language like C++, there are several constructs which turn out to be Monads, like `std::optional`, `std::vector` and others.

Everybody tries to introduce `Monad`s with a different analogy, and most people fail. This is called the [Monad tutorial fallacy][1]. We will try to avoid this trap by not presenting a specific intuition, and we will instead present what monads are mathematically. For specific intuitions, we will let readers who are new to this concept read one of the many excellent tutorials available online. Understanding Monads might take time at first, but once you get it, a lot of patterns will become obvious Monads; this enlightening will be your reward for the hard work.

There are different ways of defining a Monad; Haskell uses a function called `bind` (`>>=`) and another one called `return` (it has nothing to do with C++'s `return` statement). They then introduce relationships that must be satisfied for a type to be a Monad with those functions. Mathematicians sometimes use a function called `join` and another one called `unit`, or they also sometimes use other category theoretic constructions like functor adjunctions and the Kleisli category.

This library uses a composite approach. First, we use the `flatten` function (equivalent to `join`) along with the `lift` function from `Applicative` (equivalent to `unit`) to introduce the notion of monadic function composition. We then write the properties that must be satisfied by a Monad using this monadic composition operator, because we feel it shows the link between Monads and Monoids more clearly than other approaches.

Roughly speaking, we will say that a `Monad` is an `Applicative` which also defines a way to compose functions returning a monadic result, as opposed to only being able to compose functions returning a normal result. We will then ask for this composition to be associative and to have a neutral element, just like normal function composition. For usual composition, the neutral element is the identity function `id`. For monadic composition, the neutral element is the `lift` function defined by `Applicative`. This construction is made clearer in the laws below.

Note
  Monads are known to be a big chunk to swallow. However, it is out of the scope of this documentation to provide a full-blown explanation of the concept. The [Typeclassopedia][2] is a nice Haskell-oriented resource where more information about Monads can be found.

## Minimal complete definitions

First, a `Monad` must be both a `Functor` and an `Applicative`. Also, an implementation of `flatten` or `chain` satisfying the laws below for monadic composition must be provided.

Note
  The `ap` method for `Applicatives` may be derived from the minimal complete definition of `Monad` and `Functor`; see below for more information.

## Laws

To simplify writing the laws, we use the comparison between functions. For two functions `f` and `g`, we define

f == g if and only if f(x) == g(x) for all x
boost::hana::all
constexpr auto all
Returns whether all the keys of the structure are true-valued.
Definition: all.hpp:30

With the usual composition of functions, we are given two functions \( f : A \to B \) and \( g : B \to C \), and we must produce a new function \( compose(g, f) : A \to C \). This composition of functions is associative, which means that

compose(h, compose(g, f)) == compose(compose(h, g), f)
boost::hana::compose
constexpr auto compose
Return the composition of two functions or more.
Definition: compose.hpp:52

Also, this composition has an identity element, which is the identity function. This simply means that

compose(f, id) == compose(id, f) == f

This is probably nothing new if you are reading the `Monad` laws. Now, we can observe that the above is equivalent to saying that functions with the composition operator form a `Monoid`, where the neutral element is the identity function.

Given an `Applicative` `F`, what if we wanted to compose two functions \( f : A \to F(B) \) and \( g : B \to F(C) \)? When the `Applicative` `F` is also a `Monad`, such functions taking normal values but returning monadic values are called monadic functions. To compose them, we obviously can't use normal function composition, since the domains and codomains of `f` and `g` do not match properly. Instead, we'll need a new operator – let's call it `monadic_compose`:

## Variables
template<typename M >
constexpr auto | boost::hana::tap
| Tap inside a monadic chain. More...
constexpr auto | boost::hana::then
| Sequentially compose two monadic actions, discarding any value produced by the first but not its effects. More...

## Variable Documentation

## ◆ tap

template<typename M >

constexpr auto boost::hana::tap
| constexpr

`#include <boost/hana/fwd/tap.hpp>`

Initial value:
= [](auto&& f) {
return tag-dispatched;
}

Tap inside a monadic chain.

Given a function `f`, `tap<M>` returns a new function which performs `f` on its argument and then returns the argument lifted in the `M` `Monad`. Combined with the property that `chain(m, lift<M>) == m`, this provides a way of executing an action inside a monadic chain without influencing its overall result. This is useful to e.g. insert debug statements or perform actions that are not tied to the chain but that need to be executed inside of it.

Note
  Since C++ is not a pure language, it is possible to perform side effects inside the `f` function. Actually, side effects are the only reason why one might want to use `tap`. However, one should not rely on the side effects being done in any specific order.

Template Parameters

  M | The tag (a `Monad`) of the monads in the tapped monadic chain.

Parameters

  f | A function to be executed inside a monadic chain. It will be called as `f(x)`, where `x` is a value inside the previous monad in the chain. The result of `f` is always discarded.

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/assert.hpp>
#include <boost/hana/chain.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/tap.hpp>
#include <boost/hana/tuple.hpp>
#include <set>
namespace hana = boost::hana;
int main() {
// We use a sorted container because the order in which the functions
// are called is unspecified.
std::set<int> before, after;
auto xs = hana::make_tuple(1, 2, 3)
| hana::tap<hana::tuple_tag>([&](int x) { before.insert(x); })
| [](auto x) { return hana::make_tuple(x, -x); }
| hana::tap<hana::tuple_tag>([&](int x) { after.insert(x); });
BOOST_HANA_RUNTIME_CHECK(before == std::set<int>{1, 2, 3});
BOOST_HANA_RUNTIME_CHECK(after == std::set<int>{1, -1, 2, -2, 3, -3});
BOOST_HANA_RUNTIME_CHECK(xs == hana::make_tuple(1, -1, 2, -2, 3, -3));
}
assert.hpp
Defines macros to perform different kinds of assertions.
chain.hpp
Defines boost::hana::chain.
equal.hpp
Defines boost::hana::equal.
BOOST_HANA_RUNTIME_CHECK
#define BOOST_HANA_RUNTIME_CHECK(...)
Equivalent to BOOST_HANA_RUNTIME_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIO...
Definition: assert.hpp:209
boost::hana
Namespace containing everything in the library.
Definition: accessors.hpp:20
tap.hpp
Defines boost::hana::tap.
tuple.hpp
Defines boost::hana::tuple.

## ◆ then

constexpr auto boost::hana::then
| constexpr

`#include <boost/hana/fwd/then.hpp>`

Initial value:
= [](auto&& before, auto&& xs) -> decltype(auto) {
return tag-dispatched;
}

Sequentially compose two monadic actions, discarding any value produced by the first but not its effects.

Parameters

  before | The first `Monad` in the monadic composition chain. The result of this monad is ignored, but its effects are combined with that of the second monad.
  xs | The second `Monad` in the monadic composition chain.

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/equal.hpp>
#include <boost/hana/then.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
struct undefined { };
static_assert(
hana::then(hana::make_tuple(undefined{}, undefined{}), hana::make_tuple(1, 2, 3))
==
hana::make_tuple(
1, 2, 3,
1, 2, 3
)
, "");
int main() { }
boost::hana::then
constexpr auto then
Sequentially compose two monadic actions, discarding any value produced by the first but not its effe...
Definition: then.hpp:36
then.hpp
Defines boost::hana::then.