Last active
November 4, 2022 15:35
-
-
Save gigamonkey/af900343d0f16d729f1e55a905ccde43 to your computer and use it in GitHub Desktop.
Demonstration of Church numerals and booleans in Javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Church numerals -- functions of two arguments, a function and a zero value. | |
// The nth Church numeral applies an n-fold compostion f to the zero value. | |
const Zero = (f, z) => z; | |
const One = (f, z) => f(z); | |
const Two = (f, z) => f(f(z)); | |
const Three = (f, z) => f(f(f(z))); | |
// etc. | |
/* | |
Alternatively we can define a Successor function that takes a Church numeral, | |
n, and produces the next Church numeral and then we can build all the numerals | |
starting from Zero. | |
const Successor = (n) => (f, z) => f(n(f, z)); | |
const One = Successor(Zero); | |
const Two = Successor(One); | |
const Three = Successor(Two); | |
// etc. | |
*/ | |
// Numeric functions. The argument m and n are Church numerals as defined above, | |
// i.e. functions. | |
const Add = (m, n) => (f, z) => m(f, n(f, z)); | |
const Multiply = (m, n) => (f, z) => m((x) => n(f, x), z); | |
// Church booleans | |
const True = (a, b) => a; | |
const False = (a, b) => b; | |
// Some predicates on numbers. N.B. no if's anywhere. | |
const IsZero = (n) => n((_) => False, True); | |
const IsEven = (n) => n((b) => b(False, True), True); | |
// The i/o layer -- to interact with the Church values we need to invoke the | |
// Church value functions with arguments that let us cross the bridge between | |
// Javascript and the Church "machine". But the specific values could be | |
// anything that suits our needs. (To get all abstract mathematical, the zero | |
// value and the function probably need to form a monoid.) | |
const evalNumber = (n) => n((x) => x + 1, 0); | |
const evalBoolean = (b) => b('TRUE', 'FALSE'); | |
console.log(` | |
Do some math: | |
Zero: ${evalNumber(Zero)} | |
One: ${evalNumber(One)} | |
Two: ${evalNumber(Two)} | |
Three: ${evalNumber(Three)} | |
One + Two + Three: ${evalNumber(Add(Add(One, Two), Three))} | |
Two * Three: ${evalNumber(Multiply(Two, Three))} | |
(One + Two) * (Two + Three): ${evalNumber(Multiply(Add(One, Two), Add(Two, Three)))} | |
Booleans: | |
Zero is zero: ${evalBoolean(IsZero(Zero))} | |
One is zero: ${evalBoolean(IsZero(One))} | |
Zero is even: ${evalBoolean(IsEven(Zero))} | |
One is even: ${evalBoolean(IsEven(One))} | |
Two is even: ${evalBoolean(IsEven(Two))} | |
Three is even: ${evalBoolean(IsEven(Three))} | |
Two + Three is even: ${evalBoolean(IsEven(Add(Two, Three)))} | |
`); |
Author
gigamonkey
commented
Nov 4, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment