在本系列文中,所有的程式碼以及測試都可以在 should-i-use-fp-ts 找到,今日的範例放在 src/day-13
並且有習題和測試可以讓大家練習。
昨天的示範中有使用到兩個函數 O.fromNullable
以及 O.fromPredicate
,這兩個函式可以用來判斷當前的變數是否合法,以下是 O.fromNullable
的定義,如果當前變數(x)是 undefined
或是 null
就回傳 O.none
,否則回傳 O.some(x)
。
/** If x is null or undefined, return O.none, else O.some(x) */
type FromNullable = <A>(x: A) => O.Option<NonNullable<A>>;
const fromNullable: FromNullable = x => x === undefined || x === null ? O.none : O.some(x)
O.fromPredicate
的使用方法可以視為 Array.filter
在 Option
中的實作,一樣是傳入一個 predicate function ((x: A) => boolean)
來判斷變數是否合法,是則回傳 O.some(x)
否則回傳 O.none
。
/** If predicate(x) is true, return O.some(x), else O.none */
type FromPredicate = <A>(predicate: (x: A) => boolean) => (x: A) => O.Option<A>;
/** fromPredicate need to inject predicate function first(to validate following variable) */
const fromPredicate: FromPredicate = predicate => x => predicate(x) ? O.some(x) : O.none;
這兩項函數在日常中有很高的使用率,以下用一個 request 來做範例。
先定義 request 的 type: Req
type Req = { query: { str?: string; id: number } };
str
的部分我們可以使用 O.fromNullable
來判斷是否為空。
const isStringEmpty = (req: Req) => pipe(
req.query.str,
O.fromNullable,
O.map(str => `${str} is not empty`),
O.getOrElse(() => 'is empty'),
);
id
的部分可以用 O.fromPredicate
來判斷是否合法 (id > 0
)
const isIdValid = (req: Req) => pipe(
req.query.id,
O.fromPredicate(id => id > 0),
O.map(id => `${id} is valid`),
O.getOrElse(() => 'is invalid'),
);
今天的主題在 should-i-use-fp-ts src/day-13
有習題和測試可以練習,大家可以嘗試自己能不能寫出自己的 fromNullable
, fromPredicate
。