Last active
March 17, 2018 03:34
-
-
Save JustinSDK/9e3744420447c403d98b0df08cf673bb 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
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