Skip to content

Instantly share code, notes, and snippets.

@JustinSDK
Last active April 20, 2018 01:13
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 JustinSDK/f98d91c9b6d1f1746fb1bd902e498fde to your computer and use it in GitHub Desktop.
Save JustinSDK/f98d91c9b6d1f1746fb1bd902e498fde to your computer and use it in GitHub Desktop.
用 ES6 箭號函式(lambda)實現的微語言之二
// 完全不使用 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