Last active
April 20, 2018 01:13
-
-
Save JustinSDK/f98d91c9b6d1f1746fb1bd902e498fde to your computer and use it in GitHub Desktop.
用 ES6 箭號函式(lambda)實現的微語言之二
This file contains 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
// 完全不使用 undefined | |
let y = f => (x => f(n => x(x)(n)))(x => f(n => x(x)(n))); | |
let yes = f => y => f; | |
let no = x => f => f; | |
let when = c => c; | |
let not = b => b(no)(yes); | |
let undef = _ => no; | |
let pair = l => r => f => f(l)(r); | |
let left = p => p(yes); | |
let right = p => p(no); | |
let nil = x => yes; | |
let con = h => t => pair(h)(t); | |
let head = left; | |
let tail = right; | |
let isEmpty = p => p(l => r => no); | |
let $0 = c => x => x; | |
let $1 = c => x => c(x); | |
let $2 = c => x => c(c(x)); | |
let $3 = c => x => c(c(c(x))); | |
let is_$0 = n => n(x => no)(yes); | |
let $$ = c => x => yes; | |
let is_$$ = n => n(x => no)(no); | |
let succ = n => c => x => c(n(c)(x)); | |
let add = m => n => n(succ)(m); | |
let pair_succ = p => pair(right(p))(succ(right(p))); | |
let prev = n => left(n(pair_succ)(pair(nil)($0))); | |
let sub = m => n => n(prev)(m); | |
let rcon = t => h => when(is_$$(h)) | |
(_ => t) | |
(_ => rcon(con(h)(t)))(undef); | |
let rev = r => l => when(isEmpty(l)) | |
(_ => r) | |
(_ => rev(con(head(l))(r))(tail(l)))(undef); | |
let reverse = l => rev(nil)(l); | |
let elems = rcon(nil); | |
let list = es => reverse(es($$)); | |
let len = l => when(isEmpty(l)) | |
(_ => $0) | |
(_ => add($1)(len(tail(l))))(undef); | |
let sum = l => when(isEmpty(l)) | |
(_ => $0) | |
(_ => add(head(l))(sum(tail(l))))(undef); | |
let map = l => f => when(isEmpty(l)) | |
(_ => nil) | |
(_ => con(f(head(l)))(map(tail(l))(f)))(undef); | |
let lt = list(elems($1)($2)($3)); | |
let lt2 = map(list(elems($1)($2)($3)))(elem => sub(elem)($1)); | |
// 底下只是便於人來檢視 | |
console.log(natural(len(lt))); // 3 | |
console.log(natural(sum(lt))); // 6 | |
console.log(array(lt2)); // [0, 1, 2] | |
function natural(n) { | |
return n(i => i + 1)(0); | |
} | |
function array(lt) { | |
function arr(acc, l) { | |
if(isEmpty(l) === yes) { | |
return acc; | |
} else { | |
return arr(acc.concat([natural(head(l))]), tail(l)); | |
} | |
} | |
return arr([], lt); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment