-
-
Save vpotravnyy/735590944b58b3ca8e5b87e6989a2148 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// Boolean logic | |
const tru = (t, f) => t() | |
const fals = (t, f) => f() | |
const not = x => (t, f) => x(f, t) | |
const and = (a, b) => (t, f) => a( | |
() => b(t, f), | |
() => f() | |
) | |
const or = (a, b) => (t, f) => a( | |
() => t(), | |
() => b(t, f) | |
) | |
// List basis | |
const emptyList = (selector) => selector(undefined, undefined, tru) | |
const prepend = (el, list) => (selector) => selector(el, list, fals) | |
const head = (list) => list((h, t, e) => h) | |
const tail = (list) => list((h, t, e) => t) | |
const isEmpty = (list) => list((h, t, e) => e) | |
const map = (list, fn) => isEmpty(list)( | |
() => emptyList, | |
() => prepend(fn(head(list)), map(tail(list), fn)) | |
) | |
const filter = (list, fn) => isEmpty(list)( | |
() => emptyList, | |
() => fn(head(list))( | |
() => prepend(head(list), filter(tail(list), fn)), | |
() => filter(tail(list), fn) | |
) | |
) | |
// Numbers | |
const zero = emptyList | |
const isZero = n => isEmpty(n) | |
const inc = n => prepend(emptyList, n) | |
const dec = n => tail(n) | |
const one = inc(zero) | |
const two = inc(one) | |
const add = (a, b) => isZero(b)( | |
() => a, | |
() => add(inc(a), dec(b)) | |
) | |
const sub = (a, b) => isZero(b)( | |
() => a, | |
() => add(dec(a), dec(b)) | |
) | |
const mul = (a, b) => isZero(b)( | |
() => zero, | |
() => add(a, mul(a, dec(b))) | |
) | |
const pow = (a, b) => isZero(b)( | |
() => one, | |
() => mul(a, pow(a, dec(b))) | |
) | |
const isEqual = (a, b) => and(isZero(a), isZero(b))( | |
() => tru, | |
() => or(isZero(a), isZero(b))( | |
() => fals, | |
() => isEqual(dec(a), dec(b)) | |
) | |
) | |
const lessThan = (a, b) => and(isZero(a), isZero(b))( | |
() => fals, | |
() => isZero(a)( | |
() => tru, | |
() => isZero(b)( | |
() => fals, | |
() => lessThan(dec(a), dec(b)) | |
) | |
) | |
) | |
const greaterThan = (a, b) => lessThan(b, a) | |
const div = (a, b) => lessThan(a, b)( | |
() => zero, | |
() => inc(div(sub(a, b), b)) | |
) | |
const rem = (a, b) => lessThan(a, b)( | |
() => a, | |
() => rem(sub(a, b), b) | |
) | |
// Array | |
const nth = (list, n) => isZero(n)( | |
() => head(list), | |
() => nth(tail(list), dec(n)) | |
) | |
const length = (list) => isEmpty(list)( | |
() => zero, | |
() => inc(length(tail(list))) | |
) | |
const drop = (list, n) => isZero(n)( | |
() => list, | |
() => drop(tail(list), dec(n)) | |
) | |
const take = (list, n) => isZero(n)( | |
() => emptyList, | |
() => prepend(head(list), take(tail(list), dec(n))) | |
) | |
const slice = (l, start, end) => take(drop(l, start), sub(end, start)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment