Example is on https://godbolt.org/z/9x8WT5zhT
#include <vector>
#include <list>
#include <iostream>
#include <algorithm>
std::list<int> hoge = {1,6,7,9,2};
std::vector<std::string> result = {};
std::transform(hoge.cbegin(),hoge.cend(),std::back_inserter(result),
[](auto i){return "Number is: " + std::to_string(i);});
for(auto s:result){
std::cout << s << std::endl;
}
//fmap.hpp
template <template <class...> class CONTAINERIN,
template <class...> class CONTAINEROUT = CONTAINERIN,
typename ELEMENTIN,
typename LAMBDA,
typename ELEMENTOUT=std::invoke_result_t<LAMBDA, ELEMENTIN>>
auto fmap(CONTAINERIN<ELEMENTIN> args,LAMBDA&& lambda){
// ensure type checking
static_assert(std::is_invocable_v<LAMBDA, ELEMENTIN>, "the function for fmap is not invocable");
CONTAINEROUT<ELEMENTOUT> res;
std::transform(args.cbegin(), args.cend(), std::back_inserter(res), std::forward<decltype(lambda)>(lambda));
return std::move(res);
}
template parameter is input container and output container.
#include "fmap.hpp"
#include <vector>
#include <list>
#include <iostream>
std::list<int> hoge = {1,6,7,9,2};
auto strings = fmap<std::list,std::vector>(hoge,[](auto&& i){ return "Number is: " + std::to_string(i);});
for(auto s:result){
std:cout << s << std::endl;
}
If the container kinds between input and output are the same, you can omit template parameters.
std::list<int> hoge = {1,6,7,9,2};
//now the strings is std::list<std::string>.
auto strings = fmap(hoge,[](auto&& i){ return "Number is: " + std::to_string(i);});
for(auto s:result){
std:cout << s << std::endl;
}
//foldl.hpp
#include <type_traits>
#include <numeric>
template<template <class...> class CONTAINER,
typename RES,
typename LAMBDA>
auto foldl(CONTAINER<RES> input ,LAMBDA&& lambda){
return std::accumulate(input.cbegin(),input.cend(),RES{},std::forward<decltype(lambda)>(lambda));
}
#include "fmap.hpp"
#include "foldl.hpp"
#include <vector>
#include <list>
#include <iostream>
std::list<int> hoge = {1,6,7,9,2};
auto result =foldl(fmap(hoge,
[](auto&& i){ return "Number is: " + std::to_string(i);}),
[](auto&& s1,auto&& s2){ return s1 + "\n" + s2;}) ;
std::cout << result <<std::endl;