if else
在 Imperative 視為理所當然,但在 FP 卻是中斷 Function Pipeline 殺手,常常 Function 無法組合都是因為 if else
介入,透過 Wink-fp 的 iif()
,可使 Function Pipeline 不中斷。
Version
macOS Catalina 10.15.6
Wink-fp 1.20.81
Imperative
let f = n => {
if (n !== 1) return false
return 100
}
f(1) // ?
f(2) // ?
實務上常需要對 argument 進行判斷,若不符合條件則使用 guard clause 提早 return false
,符合條件則繼續。
&& Operator
let f = arg => (arg === 1) && 100
f(1) // ?
f(2) // ?
也可藉由 &&
對 truthy value 特性完成。
Functional
import { pipe, always, equals } from 'ramda'
let iif = f => arg => arg && f()
let f = pipe(
equals(1),
iif(always(100))
)
f(1) // ?
f(2) // ?
但 &&
畢竟是 operator 無法 Function Pipeline,可將 &&
以 iif()
實現,為了方便 point-free,將 data 放在最後一個 argument。
如此在 pipe()
時,iif()
就能接受前一個 function 傳來的值,而不需要變數。
Wink-fp
import { pipe, always, equals } from 'ramda'
import { iif } from 'wink-fp'
let f = pipe(
equals(1),
iif(always(100))
)
f(1) // ?
f(2) // ?
Wink-fp 已經內建 iif()
可直接使用。
iif()
(a -> a) -> Boolean -> a
若 data 為true
,則執行 callback 並回傳其值
(a -> a)
:要執行的 function
Boolean
:data 為 Boolean
a
:回傳執行結果
iif()
本質為&&
operator 的 function 封裝
Conclusion
- Operator 乍看之下很討喜,其實都是中斷 Function Pipeline 殺手,因為 operator 必定要搭配變數,但 Function Pipeline 是不用變數的,因此可自行將這些 operator 包成 function,這就是
iif()
目的 iif()
似乎與 Ramda 的when()
很類似,when()
必須接受兩個 function,而iif()
只需接受一個 function,且iif()
會自動轉型成 truthy value 或 falsy value,when()
必須明確轉型