Skip to content

Instantly share code, notes, and snippets.

@yyyanghj
Last active September 17, 2022 08:26
Show Gist options
  • Save yyyanghj/8cdb77fbfbb53959b380d42f6261d4d5 to your computer and use it in GitHub Desktop.
Save yyyanghj/8cdb77fbfbb53959b380d42f6261d4d5 to your computer and use it in GitHub Desktop.
const If = p => a => b => p(a)(b)
const True = a => b => a
const False = a => b => b
const One = s => z => s(z);
const Two = s => z => s(s(z));
const Three = s => z => s(s(s(z)));
const Succ = n => f => x => f(n(f)(x))
const Plus = m => n => f => x => m(f)(n(f)(x))
// z combinator
const z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)))
const Pair = x => y => z => z(x)(y)
const First = p => p(x => y => x)
const Second = p => p(x => y => y)
// List
const Cons = Pair
const Head = First
const Tail = Second
const Nil = False
const isNil = l => l(h => t => d => False)(True)
const Map = z(map => list => f => {
// 由于 js 立即求值会爆栈, 这里包装一下
return If(isNil(list))((/* thunk */) => Nil)(
(/* thunk */) => Cons(f(Head(list)))(map(Tail(list))(f)(/* Map 返回的实际上是个 thunk, 这里手动调用一次 */))
)
})
// [1, 2, 3]
const input = Cons(One)(Cons(Two)(Cons(Three)(Nil)))
const AddOne = x => Plus(x)(One)
// [2, 3, 4]
const result = Map(input)(AddOne)(/* Map 返回的实际上是个 thunk, 这里手动调用一次 */)
console.log('Input:', convertNumList(input))
console.log('Result:', convertNumList(result))
// Helpers
function convertNumList(listNode) {
let current = listNode
const res = []
while (isNil(current)(false)(true)) {
res.push(convert(Head(current)))
current = Tail(current)
}
return res
}
function s(n) {
return n + 1
}
function convert(f) {
return f(s)(0)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment