Skip to content

Instantly share code, notes, and snippets.

@anton-kapelyushok
Last active March 15, 2018 22:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anton-kapelyushok/f14998936ca6625b80ac5eeacd871977 to your computer and use it in GitHub Desktop.
Save anton-kapelyushok/f14998936ca6625b80ac5eeacd871977 to your computer and use it in GitHub Desktop.
const True = (a, b) => a()
const False = (a, b) => b()
const If = (cond, then, else_ = () => {}) => cond(then, else_)
const L = (first, second) => second(first())
const Not = (bool) => (a, b) => bool(b, a)
const Or = (bool1, bool2) => (a, b) => bool1(a, () => bool2(a, b))
const And = (bool1, bool2) => (a, b) => bool1(() => bool2(a, b), b)
const Xor = (l, r) => Or(And(Not(l), r), And(l, Not(r)))
const Xnor = (l, r) => Not(Xor(l, r))
const tr = (that, trans) => (ret) => ret(Xor(that, trans), And(that, trans))
const Inc = (num) => (n) => num((_a, _b, _c, _d) =>
tr(_d, True)((d, trans) =>
tr(_c, trans)((c, trans) =>
tr(_b, trans)((b, trans) =>
tr(_a, trans)((a, trans) => n(a, b, c, d))))))
const Inv = (num) => (n) => num((a, b, c, d) => n(Not(a), Not(b), Not(c), Not(d)))
const Dec = (num) => Inv(Inc(Inv(num)))
const _Eq = (left, right, next) =>
And(
Xnor(left, right),
next())
const Eq = (left, right) => left((la, lb, lc, ld) => right((ra, rb, rc, rd) =>
_Eq(la, ra, () =>
_Eq(lb, rb, () =>
_Eq(lc, rc, () =>
_Eq(ld, rd, () => True))))))
const _Less = (left, right, next) =>
Or(
And(Not(left), right),
And(Xnor(left, right), next())
)
const Less = (left, right) => left((la, lb, lc, ld) => right((ra, rb, rc, rd) =>
_Less(la, ra, () =>
_Less(lb, rb, () =>
_Less(lc, rc, () =>
_Less(ld, rd, () => False))))))
const LessOrEq = (left, right) => Or(Less(left, right), Eq(left, right))
const Greater = (left, right) => Not(LessOrEq(left, right))
const GreaterOrEq = (left, right) => Not(Less(left, right))
const _Plus = (_plus, left, right) =>
If(Eq(Zero, right),
() => left,
() => _plus(_plus, Inc(left), Dec(right)))
const Plus = (left, right) => _Plus(_Plus, left, right)
const Minus = (left, right) => Inv(Plus(Inv(left), right))
const _Mult = (_mult, left, right, acc) =>
If(Eq(Zero, right),
() => acc,
() => _mult(_mult, left, Dec(right), Plus(acc, left)))
const Mult = (left, right) => _Mult(_Mult, left, right, Zero)
const _Div = (_div, left, right, count) =>
If(Less(left, right),
() => count,
() => _div(_div, Minus(left, right), right, Inc(count)))
const Div = (left, right) => _Div(_Div, left, right, Zero)
const _Mod = (_mod, left, right) =>
If(Less(left, right),
() => left,
() => _mod(_mod, Minus(left, right), right))
const Mod = (left, right) => _Mod(_Mod, left, right)
//-----------------------------------------------
const toNumber = (num) => num((a, b, c, d) => {
let sum = 0
a(() => sum += 1 << 3, () => {})
b(() => sum += 1 << 2, () => {})
c(() => sum += 1 << 1, () => {})
d(() => sum += 1 << 0, () => {})
return sum
})
const toBoolean = (b) => {
let res = false
b(() => res = true, () => res = false)
return res
}
const Zero = (n) => n(False, False, False, False)
const One = (n) => n(False, False, False, True)
const Two = (n) => n(False, False, True, False)
const Three = (n) => n(False, False, True, True)
const Four = (n) => n(False, True, False, False)
const Five = (n) => n(False, True, False, True)
const Six = (n) => n(False, True, True, False)
const Seven = (n) => n(False, True, True, True)
const Eight = (n) => n(True, False, False, False)
const _For = (_for, start, cond, step) =>
If(cond(start),
() => _for(_for, step(start), cond, step),
() => start)
const For = (start, cond, step) => _For(_For, start, cond, step)
console.log(toNumber(For(Zero, (n) => Less(n, One), (n) => Inc(n))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment