Skip to content

Instantly share code, notes, and snippets.

@JustinSDK
Last active March 17, 2018 03:34
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/9e3744420447c403d98b0df08cf673bb to your computer and use it in GitHub Desktop.
Save JustinSDK/9e3744420447c403d98b0df08cf673bb to your computer and use it in GitHub Desktop.
用 ES6 箭號函式(lambda)實現的微語言之一
let yes = f => y => f();
let no = x => f => f();
let not = b => b(() => no)(() => yes);
let when = c => c;
let undef = (_ => _)();
// 系統邊界 ... 在這邊就是借助 JavaScript 執行環境,這讓事情簡單一些
let is_undef = n => n === undef ? yes : no;
let pair = l => r => f => f(l)(r);
let left = p => p(l => _ => l);
let right = p => p(_ => r => r);
let nil = pair(undef)(undef);
let con = h => t => pair(h)(t);
let head = left;
let tail = right;
let isEmpty = l => is_undef(head(l));
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 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(undef)($0)));
let sub = m => n => n(prev)(m);
let rcon = t => h => when(is_undef(h))
(() => t)
(() => rcon(con(h)(t)));
let rev = r => l => when(isEmpty(l))
(() => r)
(() => rev(con(head(l))(r))(tail(l)));
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))));
let sum = l => when(isEmpty(l))
(() => $0)
(() => add(head(l))(sum(tail(l))));
let map = l => f => when(isEmpty(l))
(() => nil)
(() => con(f(head(l)))(map(tail(l))(f)));
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