Skip to content

Commit

Permalink
Update 1.3's C++ concept implementation of Monoid (#259)
Browse files Browse the repository at this point in the history
Co-authored-by: Alfonso Ros <[email protected]>
  • Loading branch information
rosds and Alfonso Ros authored Oct 27, 2020
1 parent fab316e commit f15abcd
Showing 1 changed file with 18 additions and 17 deletions.
35 changes: 18 additions & 17 deletions src/content/1.3/categories-great-and-small.tex
Original file line number Diff line number Diff line change
Expand Up @@ -177,41 +177,42 @@ \section{Monoid as Set}
so this might be a little confusing to the beginner.)

The closest one can get to declaring a monoid in C++ would be to use the
(proposed) syntax for concepts.
C++20 standard's concept feature.

\begin{snip}{cpp}
template<class T>
T mempty = delete;
struct mempty;

template<class T>
T mappend(T, T) = delete;
template<class M>
concept bool Monoid = requires (M m) {
{ mempty<M> } -> M;
{ mappend(m, m); } -> M;
};
T mappend(T, T) = delete;

template<class M>
concept Monoid = requires (M m) {
{ mempty<M>::value() } -> std::same_as<M>;
{ mappend(m, m) } -> std::same_as<M>;
};
\end{snip}
The first definition uses a value template (also proposed). A
polymorphic value is a family of values --- a different value for every
type.
The first definition is a structure meant to hold the neutral element for each
specialization.

The keyword \code{delete} means that there is no default value
defined: It will have to be specified on a case-by-case basis.
Similarly, there is no default for \code{mappend}.

The concept \code{Monoid} is a predicate (hence the \code{bool}
type) that tests whether there exist appropriate definitions of
The concept \code{Monoid} tests whether there exist appropriate definitions of
\code{mempty} and \code{mappend} for a given type \code{M}.

An instantiation of the Monoid concept can be accomplished by providing
appropriate specializations and overloads:

\begin{snip}{cpp}
template<>
std::string mempty<std::string> = {""};
struct mempty<std::string> {
static std::string value() { return ""; }
};

std::string mappend(std::string s1, std::string s2) {
template<>
std::string mappend(std::string s1, std::string s2) {
return s1 + s2;
}
\end{snip}
Expand Down

0 comments on commit f15abcd

Please sign in to comment.