-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcps.cpp
More file actions
97 lines (66 loc) · 1.52 KB
/
cps.cpp
File metadata and controls
97 lines (66 loc) · 1.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <functional>
#include <iostream>
namespace cps {
template<class R, class A>
using cont = std::function<R(A)>;
template<class R, class A>
using monad = std::function<R(cont<R, A>)>;
template<class A>
struct pure_type {
const A a;
template<class Cont>
auto operator()(const Cont& cont) const {
return cont(a);
}
};
template<class A>
static pure_type<A> pure(const A& a) { return {a}; }
template<class CA, class Func>
struct bind_type {
const CA ca;
const Func func;
template<class Cont>
auto operator()(const Cont& cont) const {
return ca([&](const auto& a) {
return func(a)(cont);
});
}
};
template<class CA, class Func>
static bind_type<CA, Func> operator>>(const CA& ca, const Func& func) {
return {ca, func};
}
template<class Func, class Cont>
auto run(const Func& func, const Cont& cont) {
return func(cont);
}
struct yield {
template<class Cont>
Cont operator()(const Cont& cont) const {
return cont;
}
};
}
int main(int, char**) {
using namespace cps;
const auto func = pure(5) >> [=](auto a) {
return pure(10) >> [=](auto b) {
return pure(a + b);
};
};
const auto func2 = yield() >> [=](int a) {
std::clog << "a: " << a << std::endl;
const int aa = a;
return yield() >> [=](int b) {
std::clog << "b: " << b << ", a: " << aa << std::endl;
return pure(aa + b);
};
};
const auto show = [](const auto& x) {
std::clog << "show: " << x << std::endl;
};
func(show);
auto k = func2(show);
k(4)(5);
return 0;
}