/** * 畳み込みを計算する(foldl式) * @param[in] mode モード(FOLD_ADD: 和,FOLD_SUB: 差, FOLD_MULTI: 積, FOLD_DIV: 商) * @param[in] init 初期値 * @param[in] ary 入力配列 * @param[in] from 開始インデックス * @param[in] to 終了インデックス * @return resultの要素数 */ double foldl(int mode, double init, const double *ary, int from, int to) { if ( from <= to ) { switch ( mode ) { case FOLD_ADD: return foldl(mode, init, ary, from, to - 1) + ary[to]; break; case FOLD_SUB: return foldl(mode, init, ary, from, to - 1) - ary[to]; break; case FOLD_MULT: return foldl(mode, init, ary, from, to - 1) * ary[to]; break; case FOLD_DIV: return foldl(mode, init, ary, from, to - 1) / ary[to]; break; default: return 0; break; } } else { return init; } }
static constexpr decltype(auto) apply(N&& n, S&& s, F f) { return foldl( std::forward<N>(n).subforest, f(std::forward<S>(s), std::forward<N>(n).value), [=](auto&& state, auto&& subtree) -> decltype(auto) { return foldl( std::forward<decltype(subtree)>(subtree), std::forward<decltype(state)>(state), f ); } ); }
int main(){ list L = cons(1,cons(5,cons(3,cons(8,nil)))); write("Erlang: foldl (xmy, 0, L) = (8-(3-(5-(1-0)))) = "); writeln(foldl(xmy, 0, L)); write("Haskell: foldlH(xmy, 0, L) = ((((0-1)-5)-3)-8) = "); writeln(foldlH(xmy, 0, L)); write("Erlang: foldl (ymx, 0, L) = ((((0-1)-5)-3)-8) = "); writeln(foldl(ymx, 0, L)); write("Haskell: foldlH(ymx, 0, L) = (8-(3-(5-(1-0)))) = "); writeln(foldlH(ymx, 0, L)); write(" foldr (xmy, 0, L) = (1-(5-(3-(8-0)))) = "); writeln(foldr(xmy, 0, L)); }
int fold_2() { std::forward_list<int> L = {1,-6,23,78,45,13}; //std::function<int (int, int) > max = [] (int x, int y) { if (x > y) {return x;} else {return y;}}; std::function<int (int, int) > max = [] (int x, int y) { return (x > y) ? x : y;}; auto m = foldl(max, L); std::cout << m << std::endl; return 0; }
/* Return the division of the expressions */ static exp_t * prim_div(exp_t *args) { if (isnull(args)) everr("/: need at least one argument -- given", null); else if(isnull(cdr(args))) return divs(nfixnum(1), car(args)); return foldl(divs, car(args), cdr(args)); }
/* Return the cumulated substraction of the arguments */ static exp_t * prim_sub(exp_t *args) { if (isnull(args)) everr("- : need at least one argument, given", null); else if (isnull(cdr(args))) return sub(nfixnum(0), car(args)); return foldl(sub, car(args), cdr(args)); }
namespace boost { namespace hana { struct Function { struct hana { struct operators : boost::hana::operators::of<Comparable> { }; }; }; template <typename Domain, typename Codomain, typename F, typename = operators::adl> struct function_type { struct hana { using datatype = Function; }; Domain dom; Codomain cod; F def; friend constexpr auto domain(function_type f) { return f.dom; } friend constexpr auto codomain(function_type f) { return f.cod; } template <typename X> constexpr auto operator()(X x) const { if (!elem(domain(*this), x)) throw std::domain_error{"use of a hana::function with an argument out of the domain"}; return def(x); } }; BOOST_HANA_CONSTEXPR_LAMBDA auto function = [](auto domain, auto codomain) { return [=](auto definition) { return function_type<decltype(domain), decltype(codomain), decltype(definition)>{ domain, codomain, definition }; }; }; BOOST_HANA_CONSTEXPR_LAMBDA auto frange = [](auto f) { // Note: that would be better handled by a set data structure, but // whatever for now. return foldl(transform(domain(f), f), make<Tuple>(), [](auto xs, auto x) { return if_(elem(xs, x), xs, prepend(x, xs)); }); }; template <> struct equal_impl<Function, Function> { template <typename F, typename G> static constexpr auto apply(F f, G g) { return domain(f) == domain(g) && all_of(domain(f), demux(equal)(f, g)); } }; }} // end namespace boost::hana
namespace boost { namespace hana { namespace test { template <typename T> auto laws<Foldable, T> = [] { static_assert(models<Foldable(T)>{}, ""); auto f = injection([]{}); auto s = injection([]{})(); for_each(objects<T>, [=](auto xs) { BOOST_HANA_CHECK(equal( foldl(xs, s, f), foldl(to<Tuple>(xs), s, f) )); BOOST_HANA_CHECK(equal( foldr(xs, s, f), foldr(to<Tuple>(xs), s, f) )); }); }; }}} // end namespace boost::hana::test
void testHigher() { std::string str = "abcd"; auto lst = fromIt(str.begin(), str.end()); auto lst2 = fmap<char>(toupper, lst); std::cout << lst2 << std::endl; auto result = foldr([](char c, std::string str) { return str + c; }, std::string(), lst2); std::cout << result << std::endl; auto result2 = foldl([](std::string str, char c) { return str + c; }, std::string(), lst2); std::cout << result2 << std::endl; std::string mix = "TooMuchInformation"; auto lst3 = filter(isupper, fromIt(mix.begin(), mix.end())); std::cout << lst3 << std::endl; }
/* An abstraction of recursively traversing a list from left to right */ static void *foldl(void *(*f)(void *acc, void *data), void *acc, List list) { return !list ? acc : foldl(f, f(acc, list->data), list->next); }
decltype(auto) foldl(Op&&op, Var i1, Var i2, Pack... ip) { if constexpr ( sizeof...(ip) ) { return foldl(op, op(i1, i2), ip...); } else { return op(i1, i2);
// hajtogatás balról, Erlang stílusban // foldl(F, a, [x1,...,xn]) = F(xn, ..., F(x1, a)...) int foldl(const fun2 F, const int A, const list L) { if (L == nil) return A; else return foldl(F, F(hd(L), A), tl(L)); }
/* Return the product of the expressions */ static exp_t * prim_prod(exp_t *args) { return foldl(prod, nfixnum(1), args); }
/* Return the sum of the expressions */ static exp_t * prim_add(exp_t *args) { return foldl(add, nfixnum(0), args); }
/* Return the length of the list */ int len(List list) { return (long) foldl(plus_one, 0, list); }
static constexpr auto foldl_impl(X x, S s, F f) { return foldl(members<R>, s, [=](auto s, auto k_f) { return f(s, second(k_f)(x)); }); }
/* Returns a reversed copy of list */ List reverse(List list) { return (List) foldl((void *(*)(void *, void *))push, NULL, list); }
// foldl1(F, [x1, ..., xn]) = F(...(F(F(x1, x2), x3), ...), xn) int foldl1(const fun2 F, const list L) { return foldl(F, hd(L), tl(L)); }