Church numerals: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (Automated syntax highlighting fixup (second round - minor fixes)) |
(C++ entry) |
||
Line 257: | Line 257: | ||
<pre>7 12 64 81 1 3 1 3 4</pre> |
<pre>7 12 64 81 1 3 1 3 4</pre> |
||
The Church Division function is implemented by recursively counting the number of times the divisor can be subtracted from the dividend until it reaches zero, and as C# methods do not allow direct recursion, rather than using a Y-Combinator to implement this just uses mutually recursive private sub methods. |
The Church Division function is implemented by recursively counting the number of times the divisor can be subtracted from the dividend until it reaches zero, and as C# methods do not allow direct recursion, rather than using a Y-Combinator to implement this just uses mutually recursive private sub methods. |
||
=={{header|C++}}== |
|||
<syntaxhighlight lang="cpp">#include <iostream> |
|||
// apply the function zero times (return an identity function) |
|||
auto Zero() { |
|||
return [](auto) { |
|||
return [=](auto x) {return x;}; |
|||
}; |
|||
} |
|||
// apply the function f one more time |
|||
auto Successor(auto church) { |
|||
return [=](auto f) { |
|||
return [=](auto x) { |
|||
return church(f)(f(x)); |
|||
}; |
|||
}; |
|||
} |
|||
// apply the function a times after b times |
|||
auto Add(auto a, auto b) { |
|||
return [=](auto f) { |
|||
return [=](auto x) { |
|||
return a(f)(b(f)(x)); |
|||
}; |
|||
}; |
|||
} |
|||
// apply the function a times b times |
|||
auto Multiply(auto a, auto b) { |
|||
return [=](auto f) { |
|||
return a(b(f)); |
|||
}; |
|||
} |
|||
// apply the function a^b times |
|||
auto Exp(auto a, auto b) { |
|||
return b(a); |
|||
} |
|||
// create a Church numeral from an integer at compile time |
|||
template <int N> constexpr auto ToChurch() { |
|||
if constexpr(N<=0) return Zero(); |
|||
else return Successor(ToChurch<N-1>()); |
|||
} |
|||
// use an increment function to convert the Church number to an integer |
|||
int ToInt(auto church) { |
|||
return church([](int n){return n + 1;})(0); |
|||
} |
|||
int main() { |
|||
auto zero = Zero(); |
|||
auto three = Successor(Successor(Successor(zero))); |
|||
auto four = Successor(three); |
|||
auto six = ToChurch<6>(); |
|||
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)); |
|||
std::cout << "\n 3 * 4 = " << ToInt(Multiply(three, four)); |
|||
std::cout << "\n 4 * 3 = " << ToInt(Multiply(four, three)); |
|||
std::cout << "\n 3^4 = " << ToInt(Exp(three, four)); |
|||
std::cout << "\n 4^3 = " << ToInt(Exp(four, three)); |
|||
std::cout << "\n 0^0 = " << ToInt(Exp(zero, zero)); |
|||
auto looloolooo = Add(Exp(ten, nine), Add(Exp(ten, six), Exp(ten, three))); |
|||
std::cout << "\n 10^9 + 10^6 + 10^3 = " << ToInt(looloolooo) << "\n"; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
3 + 4 = 6 |
|||
4 + 3 = 7 |
|||
3 * 4 = 12 |
|||
4 * 3 = 12 |
|||
3^4 = 81 |
|||
4^3 = 64 |
|||
0^0 = 1 |
|||
10^9 + 10^6 + 10^3 = 1001001000 |
|||
</pre> |
|||
=={{header|Chapel}}== |
=={{header|Chapel}}== |
||