# 1 map

Fixpoint map {X Y:Type} (f:X->Y) (l:list X)
: (list Y) :=
match l with
| []     => []
| h :: t => (f h) :: (map f t)
end.

template <class X, class UnaryOperation, template <class, class...> class List>
auto map(UnaryOperation f, List<X> l)
{
if (l.empty()) {
return List<decltype(f(X()))>();
}

X h = l.front();
l.pop_front();

auto ret = map(f, l);
ret.push_front(f(h));
return ret;
}

# 2 fold

Fixpoint fold {X Y:Type} (f: X->Y->Y) (l:list X) (b:Y) : Y :=
match l with
| nil => b
| h :: t => f h (fold f t b)
end.

template <class Y, class BinaryOperation, class List>
Y fold(BinaryOperation f, List l, Y b)
{
if (l.empty()) {
return b;
}

auto h = l.front();
l.pop_front();

return f(h, fold(f, l, b));
}

# 3 fold_map

Definition fold_map {X Y:Type} (f : X -> Y) (l : list X) : list Y :=
fold (fun x l => (f x) :: l) l [].

/*
* use fold to implement map
*/
template <class X, class UnaryOperation, template <class, class...> class List>
auto fold_map(UnaryOperation f, List<X> l)
{
using L = List<decltype(f(X()))>;
auto bin_fun = [&f] (X x, L lst) {
lst.push_front(f(x));
return lst;
};

return fold(bin_fun, l, L());
}

# 4 用 STL 实现 fold 和 map

template <class Y, class BinaryOperation, class List>
Y fold(BinaryOperation f, List l, Y b)
{
// reverse parameter list in f
auto binary_op = [&f] (auto a, auto b) {
return f(b, a);
};
return accumulate(crbegin(l), crend(l), b, binary_op);
}

template <class X, class UnaryOperation, template <class, class...> class List>
auto map(UnaryOperation f, List<X> l)
{
List<decltype(f(X()))> dst_list(l.size());

transform(cbegin(l), cend(l), begin(dst_list), f);

return dst_list;
}

template <class InputIterator, class Tp, class BinaryOperation>
Tp accumulate(InputIterator first, InputIterator last, Tp init, BinaryOperation binary_op)
{
for ( ; first != last; ++first) {
init = binary_op(init, *first);
}

return init;
}

Inductive list (X:Type) : Type :=
| nil : list X
| cons : X -> list X -> list X.

Arguments cons {X} _ _.  (* use underscore for argument position that has no name *)

Notation "x :: y" := (cons x y)
(at level 60, right associativity).

# 5 参考资料

[1] Software Foundations
[2] C++ Primer
[3] STL 源码剖析

# 6 附录（源程序）

#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>
#include <string>
#include <cassert>
using namespace std;

template <class Y, class BinaryOperation, class List>
Y fold(BinaryOperation f, List l, Y b)
{
if (l.empty()) {
return b;
}

auto h = l.front();
l.pop_front();

return f(h, fold(f, l, b));
}

template <class X, class UnaryOperation, template <class, class...> class List>
auto map(UnaryOperation f, List<X> l)
{
if (l.empty()) {
return List<decltype(f(X()))>();
}

X h = l.front();
l.pop_front();

auto ret = map(f, l);
ret.push_front(f(h));
return ret;
}

/*
* use fold to implement map
*/
template <class X, class UnaryOperation, template <class, class...> class List>
auto fold_map(UnaryOperation f, List<X> l)
{
using L = List<decltype(f(X()))>;
auto bin_fun = [&f] (X x, L lst) {
lst.push_front(f(x));
return lst;
};

return fold(bin_fun, l, L());
}

int main(int argc, char **argv)
{
auto f = [] (auto x) {
return "element is " + to_string(x);
};
list<short> l = {1, 2};

auto lst = fold_map(f, l);

copy(lst.begin(), lst.end(), ostream_iterator<decltype(lst)::value_type>(cout, "\n"));

assert(fold_map(f, l) == map(f, l));

return 0;
}
#include <iostream>
#include <numeric>
#include <deque>
#include <iterator>
#include <algorithm>
#include <string>
#include <cassert>
using namespace std;

template <class Y, class BinaryOperation, class List>
Y fold(BinaryOperation f, List l, Y b)
{
// reverse parameter list in f
auto binary_op = [&f] (auto a, auto b) {
return f(b, a);
};
return accumulate(crbegin(l), crend(l), b, binary_op);
}

template <class X, class UnaryOperation, template <class, class...> class List>
auto map(UnaryOperation f, List<X> l)
{
List<decltype(f(X()))> dst_list(l.size());

transform(cbegin(l), cend(l), begin(dst_list), f);

return dst_list;
}

/*
* use fold to implement map
*/
template <class X, class UnaryOperation, template <class, class...> class List>
auto fold_map(UnaryOperation f, List<X> l)
{
using L = List<decltype(f(X()))>;
auto bin_fun = [&f] (X x, L lst) {
lst.push_front(f(x));
return lst;
};

return fold(bin_fun, l, L());
}

int main(int argc, char **argv)
{
auto f = [] (auto x) {
return "element is " + to_string(x);
};
deque<short> l = {1, 2};

auto lst = fold_map(f, l);

copy(cbegin(lst), cend(lst), ostream_iterator<decltype(lst)::value_type>(cout, "\n"));

assert(fold_map(f, l) == map(f, l));

return 0;
}

10-10 30

07-26 1174

12-27 956

08-27 8354

11-26

06-26 1165

06-13 970

#### scala与函数式编程——什么是函数式编程

©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。