如何使用 Quokka 測試 Ramda ?
Ramda 是 ECMAScript 實現 Functional Programming 的神兵利器,透過 Quokka,我們可以更快速測試與學習 Ramda。
失くすものさえない今が強くなるチャンスよ
Ramda 是 ECMAScript 實現 Functional Programming 的神兵利器,透過 Quokka,我們可以更快速測試與學習 Ramda。
一直很羨慕 F# 的 List
Module 提供了豐富的 Function,而 ECMAScript 的 Array.prototype
卻只提供有限的 Function 可用,因此無法完全發揮 FP 威力。但這一切終於得到解決,Ramda 擁有豐富的 Function,且很容易自行開發 Function 與 Ramda 整合實現 Function Pipeline。
將傳入 Data 的 Function 加以 Point-free,這在 Ramda 很常見;但若 Data 傳入的目的是產生另外一個 Function,這類 Higher Order Function 可使用 ncurryN()
使其 Point-free。
若 array 中遍佈了一堆 0
,我們希望將 非 0
部分全部往前移,而 0
全部挪到最後,該如何實現呢 ?
若出現 Nested Chain,可使用 unnest()
從內層攤平一層 Chain。
symmetricDifference()
只能提供內見的比較方式,若要自行提供 Predicate,就要使用 symmetricDifferenceWith()
。
sysmmetricDifference()
是較少用的 Function,跟 difference()
有點類似,但又不太一樣。
range()
也算實務上常用的 function,只要傳入 初始值
與 結束值
,就可建立 Array,在很多語言都有內建 range()
,但可惜 ECMAScript 並沒有,但 Ramda 已經內建 range()
,可直接使用。
Ramda 的 is()
相當於 instanceOf
的 Function 版本,實務上我們我們常需要對 Object 的 Property 判斷 Type,Ramda 也提供了 propIs()
。
實務上我們常需要讀取 Object 的 Property,但我們並不確定 Object 是否有該 Property,最嚴謹的做法必須先檢查 Property 是否存在才能讀取,否則在 Runtime 可能會得到 Cannot read property xxx of undefined
的錯誤訊息。
Ramda 的 prop()
只能取出 object 單一 Property,若要取出多個 Property 成 Array,就要使用 props()
。
在 for
Loop 內呼叫 Asynchronous Function 為常見需求,Imperative 做法是在 for of
內搭配 await
與 Side Effect 完成,但在不使用 Side Effect 的 FP 該如何實現呢 ?
實務上常遇到 API 回傳兩層 Array,其中 Object 僅包含 Flag,前端必須根據 Flag 值決定要新增的 Property,這種常見的需求該如何實現呢 ?
ECMAScript 雖然有提供 instanceof
,但其為 Operator,因此無法達成 Fuction Composition,而 Ramda 的 is()
正是 instanceof
的 Function 版本。
分組加總
也是實務上常見的需求,該如何使用 Ramda 實現呢 ?
實務上 API 所傳回的資料常常掛在 data
Property 上,且資料藏在 Nested Property 下,但 GUI 顯示常只需要一層 Array 而已,這常見需求該如何實現呢 ?
實務上為了簡化 User 操作,我們希望輸入 Keyword 後,能對 Array 內 Object 所有 Property 都進行檢查,只要包含此 Keyword,就會顯示該 Object,這該如何實現呢 ?
由於 ECMAScript 同時存在了 undefined
與 null
,因此實務上常常需要同時判斷這兩個值,Ramda 提供了 isNil()
讓我們一次判斷,語意也更清楚。
Ramda 提供了 empty()
回傳各型別的 Empty 值,同時也提供了 isEmpty()
判斷是否為 Empty 值。
在 C# 我們有 String.Empty()
來表示 空字串
取代 ""
,相同地,在 Ramda 我們有 empty()
,當 String、Object 與 Array 傳進 empty()
時,會回傳相對應的 Empty 值。
實務上我們常需要讀取 Object 的 Property,但我們並不確定 Object 是否有該 Property,最嚴謹的做法必須先檢查 Property 是否存在才能讀取,否則在 Runtime 可能會得到 Cannot read property xxx of undefined
的錯誤訊息。
若 Function 的 argument 是很深層的 object,可以使用 ECMAScript 2015 的 Object Destructuring 加以拆解,除此之外,也可以使用 Ramda 的 path()
。
初學者學習 FP 或 Ramda,會發現在 Imperative 下 Break Point 大法失效了,因為在 Pipeline 或 Compose 下,根本無從下 Break Point,此時該如何 Debug 呢 ?
Ramda 之 curry()
也是非常實用的 Function,他能將普通 Function 轉成 Curried Function,這在 FP 語言算是標準配備,但一直到目前為止,ECMAScript 都還沒有正式支援,而 Curried Function 對於寫出 Point-free Style 有很大貢獻。
若只求結果正確,Ramda 其實不難,而是難在 Callback 如何 Point-free,很多看似簡單,卻會讓你想破頭,本文整理出幾個常見的技巧,可以視為 Pattern 使用。
Ramda 之 pick()
與 pickAll()
都只能直接指定 Object 要擷取的 Property,若想要根據自訂條件選擇 Property,就只能靠 pickBy()
,且可再將 pickBy()
與其他 Function 組合成新的 Function,如此可讀性更高。
除了 pick()
外,Ramda 另外提供了 pickAll()
,若該 property 並不存在於 object,則顯示 undefined
。
實務上 map()
最常使用的就是從 Object 眾多 Property 中,僅擷取部分 Property,Ramda 提供了 pick()
達成此功能。
dropRepeats()
預設使用 equals()
判斷 Array 是否連續重複,若要提供自訂條件,就要使用 dropRepeatsWith()
。
若允許 Array 內 Element 重複,但若連續重複只取一 Element 做代表,如此就不能使用 uniq()
,只能使用 dropRepeats()
。
dropLast()
只能刪除 String 固定最後幾個 Char,若想自行提供自訂條件 Predicate,就得使用 dropLastWhile()
。
dropLast()
只能刪除 Array 固定最後幾筆資料,若想自行提供自訂條件 Predicate,就得使用 dropLastWhile()
。
實務上常遇到中間資料符合預期,但後面資料不符合規格,可使用 dropLast()
加以刪除。
drop()
只能刪除 String 固定前幾個 Char,若想自行提供自訂條件 Predicate,就得使用 dropWhile()
。
drop()
只能刪除 Array 固定前幾筆資料,若想提供自訂條件 Predicate,就得使用 dropWhile()
。
實務上常遇到中間 String 符合預期,但前面 String 不符合規格,此時可用 drop()
加以刪除。
實務上常遇到後面資料符合預期,但前面資料不符合規格,可使用 drop()
加以刪除。
ECMAScript 雖然是 Dynamic Type Language,但並不代表 Variable 沒有 Type,只是其內建獲得 Type 方法包含太多 驚喜
,成為備受爭議部分。本文整理出 4 種獲得 Type 方式,各有其優缺點,最後自訂 typeof_()
,可判斷各種 Type。
將 String 前後顛倒在實務上不太常見,不過用來練功倒是不錯,有多種實現方式。
將 Array 前後顛倒在實務上可能不太常見,不過用來練功倒是不錯,有多種實現方式。