blob: 465e58af36e7481f11b3734c227c8ae1f9f9e316 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
#pragma once
#include <numeric>
#include <vector>
/**
* A monoid is an algebraic structure with a single associative
* binary operation ('append') and an identity element ('empty').
*
* See https://en.wikipedia.org/wiki/Monoid
*
* Shamelessly adapted from:
*
* https://gist.github.com/evincarofautumn/2b5f004ca81e33c62ff0
*/
template<typename T, T append_(T const&, T const&), const T &empty_>
struct monoid {
/* Access the type the monoid operates on */
typedef T type;
/* Append two T's */
static T append(T const& a, T const& b) {
return append_(a, b);
}
/* The value of an empty T */
static constexpr T empty = empty_;
};
/**
* mconcat :: (Monoid m mappend) -> [m] -> m
* mconcat = fold mappend mempty
*/
template<typename M>
typename M::type mconcat(const std::vector<typename M::type>& xs) {
return std::accumulate(std::begin(xs), std::end(xs), M::empty, M::append);
}
|