Church numerals: Difference between revisions

→‎{{header|C++}}: Add subtraction and division
m (→‎{{header|C++}}: fix output)
(→‎{{header|C++}}: Add subtraction and division)
Line 259:
 
=={{header|C++}}==
The Church numerals are implemented using lambdas.
<syntaxhighlight lang="cpp">#include <iostream>
 
Line 269 ⟶ 270:
 
// apply the function f one more time
auto Successor(auto churcha) {
return [=](auto f) {
return [=](auto x) {
return churcha(f)(f(x));
};
};
Line 296 ⟶ 297:
auto Exp(auto a, auto b) {
return b(a);
}
 
// apply the function f one less time
auto Predecessor(auto a) {
return [=](auto f) {
return [=](auto x) {
return a(
[=](auto g) {
return [=](auto h){
return h(g(f));
};
}
)([=](auto) {return x;})([](auto y){return y;});
};
};
}
 
// apply the Predecessor function b times to a
auto Subtract(auto a, auto b) {
{
auto a_minus_b = b([](auto c){ return Predecessor(c);})(a);
 
// Each lambda has its own type which gives '3-1' a different
// type than '4-2'. Normalize the number based on successors to 0.
return a_minus_b([=](auto f) {return Successor(f);})(Zero());
};
}
 
namespace
{
// helper functions for division. These funtions are only
// visible in this source file
 
// end the recusrion
auto Divr(decltype(Zero()), auto) {
return Zero();
}
 
// count how many times b can be subtracted from a
auto Divr(auto a, auto b) {
return Successor(Divr(Subtract(a, b), b));
}
}
 
// apply the function a / b times
auto Divide(auto a, auto b) {
return Divr(Subtract(Successor(a), b), b);
}
 
Line 310 ⟶ 358:
 
int main() {
// show some examples
auto zero = Zero();
auto three = Successor(Successor(Successor(zero)));
Line 316 ⟶ 365:
auto nine = ToChurch<9>();
auto ten = Successor(nine);
 
std::cout << "\n 3 + 4 = " << ToInt(Add(three, four));
std::cout << "\n 4 + 3 = " << ToInt(Add(four, three));
Line 324 ⟶ 373:
std::cout << "\n 4^3 = " << ToInt(Exp(four, three));
std::cout << "\n 0^0 = " << ToInt(Exp(zero, zero));
std::cout << "\n 9 - 6 = " << ToInt(Subtract(nine, six));
std::cout << "\n 9 - 9 = " << ToInt(Subtract(nine, nine));
std::cout << "\n 6 / 3 = " << ToInt(Divide(six, three));
std::cout << "\n 3 / 6 = " << ToInt(Divide(three, six));
auto looloolooo = Add(Exp(ten, nine), Add(Exp(ten, six), Exp(ten, three)));
std::coutauto << "\n 10^9 + 10^6 + 10^3looloolool = " << ToIntSuccessor(looloolooo) << "\n";
std::cout << "\n 10^9 + 10^6 + 10^3 + 1 = " << ToInt(looloolool) << "\n";
}</syntaxhighlight>
{{out}}
Line 336 ⟶ 390:
4^3 = 64
0^0 = 1
10^9 +- 10^6 += 10^3 = 1001001000
9 - 9 = 0
6 / 3 = 2
3 / 6 = 0
10^9 + 10^6 + 10^3 + 1 = 1001001001
</pre>
 
125

edits