Monads in C++


Monads in C++? What a strange name for a post. But it's not so strange. With std::optional C++17 gets a monad. The ranges library from Eric Niebler and the extended futures are also monads. For both, we can hope for in C++20.

Bjarne Stroustrup presented in his Secret Lightning Talk at the Meeting C++ 2016 a few of the concepts of Concepts Lite that we will get with high probability in C++20. There were also mathematical concepts such as ring and monad. My assumption becomes more and more reality. Modern C++ will be hardened for the future.


std::optional is inspired by Haskell's Maybe Monad. std::optional that was originally intended to be part of C++14 stands for a calculation that maybe has a value. Therefore, a find algorithm or a query of a hash table has to deal with the fact that the question can not be answered. Often, you use for such cases special values that stand for the presence of no value, so-called no-result. Often we use a null pointer, empty strings of special integer values for no-results. This technique is expensive and error-prone because you have to deal with the no-results in a special way. No-results are of the same type as regular results. std::optional has in case of a no-result no value.

Here is a short example.


// optional.cpp

#include <experimental/optional>
#include <iostream>
#include <vector>

std::experimental::optional<int> getFirst(const std::vector<int>& vec){
  if (!vec.empty()) return std::experimental::optional<int>(vec[0]);
  else return std::experimental::optional<int>();

int main(){
    std::vector<int> myVec{1, 2, 3};
    std::vector<int> myEmptyVec;
    auto myInt= getFirst(myVec);
    if (myInt){
        std::cout << "*myInt: "  << *myInt << std::endl;
        std::cout << "myInt.value(): " << myInt.value() << std::endl;
        std::cout << "myInt.value_or(2017):" << myInt.value_or(2017) << std::endl;
    std::cout << std::endl;
    auto myEmptyInt= getFirst(myEmptyVec);
    if (!myEmptyInt){
        std::cout << "myEmptyInt.value_or(2017):" << myEmptyInt.value_or(2017) << std::endl;


std::optional is currently in the namespace experimental. That will change with C++17. I use std::optional in the function getFirst (line 7). getFirst returns the first element if it exists (line 8). If not, you will get a std::optional<int> object (line 9). I use in the main function two vectors. The calls getFirst in line 17 and 27 return the std::optional objects. In case of myInt (line 19), the object has a value; in case of myEmptyInt (Zeile 29), the object has no value. Now I can display the value of myInt (line 20 - 22). The method value_or in line 22 and 30 returns the value or a default value. This is due to the fact whether std::optional has a value.


The screenshot shows the output of the program using the online-compiler at


Extended futures

Modern c++ supports tasks.



Tasks are pairs of  std::promise and std::future objects connected by a channel. Both communication endpoints may exist in different threads. The std::promise (sender) pushes its value into the channel the std::future (receiver) is waiting for. The sender can push a value, a notification, or an exception into the channel. I've written a few posts about tasks. Here are the details:  Tasks.

The easiest way to create a promise is to use the function std::async. std::async behaves like an asynchronous function call.

int a= 2000
int b= 11;
std::future<int> sum= std::async([=]{ return a+b; });
std::cout << sum.get() << std::endl;


The call std::async performs more actions. First, it creates the communication endpoints promise and future; second, it connects them both via a channel. The lambda function [=]{ return a+b;} is the work package of the promise. It captures the arguments a and b from its defining context. The C++ run time decides if the promise will run in the same or in a different thread. Criteria for its decision may be size of the work package, the load of the system, or the number of cores.

The future calls sum.get() to get the value from the promise. You can only once call sum.get(). If the promise is not done with its job, the get call will block.

Tasks provide a similar and safer handling of threads because they have no shared state that has to be protected. Therefore, race conditions are not possible and dead locks much rarer. But, the C++11 implementation of futures has a big disadvantage. The composition of std::future objects is not possible. This will not hold true for the extended futures of C++20.

The table shows the functions for extended futures.


Here are a few code snippets from the proposal n3721.


future<int> f1= async([]() {return 123;});

future<string> f2 = f1.then([](future<int> f) {
     return f.get().to_string(); 

future<int> futures[] = {async([]() { return intResult(125); }), 
                         async([]() { return intResult(456); })};

future<vector<future<int>>> any_f = when_any(begin(futures), end(futures));

future<int> futures[] = {async([]() { return intResult(125); }), 
                         async([]() { return intResult(456); })};

future<vector<future<int>>> all_f = when_all(begin(futures), end(futures));


The future f2 in line 3 is ready, if the future f2 is ready. You can enlarge the chain of futures:  f1.then(...).then(...).then(...). The future any_f in line 10 becomes ready if any of its futures become ready. In contrary, the future all_f in line 16 becomes ready, if all its futures become ready.

One question is still not answered. What have futures in common with functional programming? A lot! The extended futures are a monad. I explained in the post Pure Functions the idea of monads. The key idea of a monad is that a monad encapsulates a simple type in an enriched type and supports the compositions of functions on these enriched types. Therefore, the monad needs a function for lifting the simple type into an enriched type. Additionally, a monad needs a function that empowers them to compose functions on enriched types. This is the job for the functions make_ready_future, then, and future<future<T>>. make_ready_future maps a simple type into an enriched type; a so-called monadic value. This function is called identity and has the name return in Haskell. The two functions then and future<future<T>> are equivalent to the bind operator in Haskell. The bind operators job is it to transform one monadic value into another monadic value. bind is the function composition in a monad. 

Thanks to the method when_any std::future even becomes a Monad Plus. A Monad Plus requires from its instances that they are monads and have an operator msum. Therefore, std::future supports a kind of an addition operation in C++20.

If you want to know the details, you should read the excellent blog of Bartosz Milelweski and watch his video:  "C++17: I See a Monad in Your Future!".

What's next?

In my post Recursion, List Manipulation, and Lazy Evaluation, I wrote: The story about lazy evaluation in C++ is quite short. But I made my conclusion without templates. Thanks to the CRTP idiom and expression templates C++ is lazy. Therefore, I will write in the next post about the infamous CRTP idiom.







Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, Marko, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Darshan Mody, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, espkk, Wolfgang Gärtner,  Louis St-Amour, Stephan Roslen, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Avi Kohn, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Neil Wang, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Tobi Heideman, Daniel Hufschläger, Red Trip, Alexander Schwarz, and Tornike Porchxidze.


Thanks in particular to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, and Richard Sargeant.

My special thanks to Embarcadero CBUIDER STUDIO FINAL ICONS 1024 Small



I'm happy to give online-seminars or face-to-face seminars world-wide. Please call me if you have any questions.

Bookable (Online)



Standard Seminars 

Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.


Contact Me

Modernes C++,






Tags: C++20


0 #31 Marcia 2017-07-28 11:32
Thank you for the wonderful post
0 #32 Gabriele 2017-07-28 16:53
I like the article
0 #33 Stacie 2017-07-29 17:39
This is actually helpful, thanks.
0 #34 Byron 2017-07-29 18:25
Thank you for the excellent article
0 #35 Blythe 2017-07-29 22:17
It works really well for me
0 #36 Glenn 2017-08-02 15:16
Thank you for the terrific post
0 #37 Kelsey 2017-08-03 00:38
It works quite well for me
0 #38 Helaine 2017-08-03 13:34
Thanks for the wonderful post
0 #39 Yanira 2017-11-16 18:22
Great article! We are linking to this particularly great post on our website.
Keep up the good writing.

My Newest E-Books

Course: Modern C++ Concurrency in Practice

Course: C++ Standard Library including C++14 & C++17

Course: Embedded Programming with Modern C++

Course: Generic Programming (Templates)

Course: C++ Fundamentals for Professionals

Subscribe to the newsletter (+ pdf bundle)

Blog archive

Source Code


Today 3178

Yesterday 5600

Week 47290

Month 72916

All 6093980

Currently are 180 guests and no members online

Kubik-Rubik Joomla! Extensions

Latest comments