# 初入 lambda 演算

``````let con = head => tail => [head, tail];
``````

``````let nil = [undefined, undefined];
``````

``````let lt1 = con(1)(nil);
``````

``````let lt2 = con(2)(lt1);
``````

``````let head = ([h, _]) => h;
let tail = ([_, t]) => t;
let isEmpty = lt => head(lt) === undefined;
``````

``````let rcon = tail => head => head === undefined ? tail : rcon(con(head)(tail));
``````

`rcon(nil)(1)(2)(3)()` 做的會是 `con` 的相反動作，這就是為什麼叫它 `rcon` 的原因，為了最後能建立 List，最後若呼叫函式時沒有指定元素，就將建立的 List 傳回而不再是傳回函式。

``````let rev = r => l => isEmpty(l) ? r : rev(con(head(l))(r))(tail(l));
let reverse = lt => rev(nil)(lt);
``````

``````let elems = rcon(nil);
let list = elems => reverse(elems());
``````

``````let lt = list(elems(1)(2)(3));
``````

``````let len = lt => isEmpty(lt) ? 0 : 1 + len(tail(lt));
``````

`len(list(elems(1)(2)(3)))` 會傳回 3 的結果。如果要加總一個 List 呢？

``````let sum = lt => isEmpty(lt) ? 0 : head(lt) + sum(tail(lt));
``````

`sum(list(elems(1)(2)(3)))` 會傳回 6 的結果。看起來還不錯，接著想想看，怎麼定義一個 `addOne` 函式，可以對傳入 List 中每個元素加一後傳回新 List 呢？

``````let addOne = lt => isEmpty(lt) ? nil : con(head(lt) + 1)(addOne(tail(lt)));
``````

``````let map = lt => f => isEmpty(lt) ? nil : con(f(head(lt)))(map(tail(lt))(f));
``````

``````let greaterThanThree = lt  => isEmpty(lt) ? nil :
head(lt) > 3 ? con(head(lt))(greaterThanThree(tail(lt))) :
greaterThanThree(tail(lt));
``````

``````let filter = lt => f => isEmpty(lt) ? nil :
f(head(lt)) ? con(head(lt))(filter(tail(lt))(f)) :
filter(tail(lt))(f);
``````