(1)commonly used generic functor greater<>(), lesser<>(), plus<>(), multiplies<>();
(2) bind() is to be replaced by lambda
(3) lambda is Callable Object, similar to c function pointer but extended to have pmd/pmf concept=pointer to member data/reference
(4) invoke(Callable,value) is template+ functional generic code execution.
(5) from monad functional space to classical code, decay_t(result_of_t(callable(invoke)))) would do it.
(6) reference_wrapper convert value semetic in monard
(7) function is a monad recorder to playback
#include "stdafx.h"
#include <functional>
#include <vector>
#include <algorithm>
#include <iostream>
#include <random>
using namespace std;
void tryout_result_of();
void tryout_reference_wrapper();
void tryout_function();
template <typename Range,typename Callable>
void transform_print(const Range& r, Callable c) // lambda is just a callable object from unamed type
{
for (const auto&e :r)
{
cout << invoke(c, e) << endl;
}
}
//pmd =point to member data, hard to optimize, pmf= pointer to member reference.
int main()
{
vector<int> vint{ 11,28,3,14,5,96 };
vector<string> vstr{ "test","jpmc","password","bankd","hou","pick peach los hand" };
sort(vint.begin(), vint.end(), greater<>()); //functor generic type
for (const auto&e : vint) cout << e << endl;
cout << count_if(vint.begin(), vint.end(), bind(less<>(), placeholders::_1, 9))<<endl; // avoid bind use lambda as below, bind has pmd
cout << count_if(vint.begin(), vint.end(), [](const auto& p) {return p < 5; }) << endl;
vector<pair<int, int>> vpint{ { 1,2 }, { 9,3 }, { 11, 55 } };
transform_print(vpint, [](const auto& p) {return p.first*p.second; }); // lambda is a callable object better than bind and should replace it.
transform_print(vpint, &pair<int, int>::second);
tryout_result_of();
tryout_reference_wrapper();
tryout_function();
getchar();
return 0;
}
template<typename T, typename Callable>
auto transform_sort(const vector<T>& v, Callable c)
{
vector<decay_t<result_of_t<Callable&(const T&)>>> ret;
for (const T& t : v)
{
auto i = invoke(c, t);
int ii = 0;
ret.push_back(i);
}
sort(ret.begin(), ret.end());
return ret;
}
void tryout_result_of()
{
const vector<string> v{ "test","functional","result_of","not really functional" };
auto lambda = [](const string& s) {return s.size(); };
cout << endl;
for (auto& e : transform_sort(v, lambda))
{
cout <<e<< endl;
}
}
void tryout_reference_wrapper()
{
vector<int> v(8);
auto b = v.begin(); auto e = v.end();
typedef uniform_int_distribution<int> Dist;
auto d20 = [urng = mt19937(3344), dist = Dist(1, 20)]() mutable { return dist(urng); };
generate(b, e, d20);
for (auto a : v) cout << a << ",";
cout << endl;
generate(b, e, d20); // same set of int
generate(b, e, ref(d20));
generate(b, e, ref(d20)); // different set due to reference_wrapper
}
int sum_square(int x, int y) { return x*x + y*y; }
void tryout_function()
{
vector<function<int(int, int)>> v; // record a sequence of action for later playback, only signature matter can be pmd,pmf, regular function
v.emplace_back(plus<>());
v.emplace_back(multiplies<>());
v.emplace_back(&sum_square); // can ommit &
for (int i = 10; i <= 1000; i *= 10)
v.emplace_back([i](int x, int y) {return i*x + y; });
for (const auto f : v) cout << f(1, 2) << endl;
}
Thursday, February 11, 2016
C++ <functional> concrete monad
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment