sseletskyy
3/29/2017 - 9:11 PM

## list-out-of-lambda.js

``````// 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,
)

const filter = (list, fn) => isEmpty(list)(
() => emptyList,
() => 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,
)
const sub = (a, b) => isZero(b)(
() => a,
)
const mul = (a, b) => isZero(b)(
() => zero,
)
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)(
() => 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,