Skip to content

Instantly share code, notes, and snippets.

@vpotravnyy
Forked from sjl/list-out-of-lambda.js
Last active May 19, 2017 09:02
Show Gist options
  • Save vpotravnyy/735590944b58b3ca8e5b87e6989a2148 to your computer and use it in GitHub Desktop.
Save vpotravnyy/735590944b58b3ca8e5b87e6989a2148 to your computer and use it in GitHub Desktop.
// 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