I am trying to implement the Maybe monad from Haskell using the lambda functions in C++11 and templates. Here’s what I have so far
#include<functional>
#include<iostream>
using namespace std;
template<typename T1>
struct Maybe
{
T1 data;
bool valid;
};
template<typename T1, typename T2>
Maybe<T2> operator>>=(Maybe<T1> t, std::function < Maybe<T2> (T1)> &f)
{
Maybe<T2> return_value;
if(t.valid == false)
{
return_value.valid = false;
return return_value;
}
else
{
return f(t.data);
}
}
int main()
{
Maybe<int> x = {5, true};
Maybe<int> y = {29, false};
auto z = [](int a) -> Maybe<int>
{
Maybe<int> s;
s.data = a+1;
s.valid = true;
return s;
};
Maybe<int> p = (x >>= z);
Maybe<int> q = (y >>= z);
cout<<p.data<<' '<<p.valid<<endl;
cout<<q.data<<' '<<q.valid<<endl;
}
When it comes to the actual >>= call, I am getting a compiler error saying that no match found for >>= operator. Is my understanding of C++11’s lambda functions failing me here?
The type of a lambda isn’t a specialization of
std::function. It’s some unamed type. There is a conversion tostd::function, but that means type deduction won’t work for it. So, in this call:The type
T2can’t be deduced:Store the lambda in a
std::functionvariable from the start, and it should work:However, it’s probably easier to accept any kind of function object. That way you can still use
autofor the lambda.