Ramda 的 is()
相當於 instanceOf
的 Function 版本,實務上我們我們常需要對 Object 的 Property 判斷 Type,Ramda 也提供了 propIs()
。
Version
macOS Mojave 10.14.6
VS Code 1.38.1
Quokka 1.0.251
Ramda 0.26.1
Functional
import { pipe, prop, is } from 'ramda';
let data = {
name: 'Sam'
};
let propIs = type => name => pipe(
prop(name),
is(type)
);
let fn = propIs(String)('name');
fn(data); // ?
data
為 object,我們想判斷其 name
property 是否為 String
type。
根據過去的經驗,我們知道 prop()
可讀取 property,is()
可判斷 type,因此可輕易組合 prop()
與 is()
產生新的 propIs()
。
Point-free
import { pipe, prop, is, flip, useWith } from 'ramda';
let data = {
name: 'Sam'
};
let propIs = flip(useWith(
pipe, [prop, is]
));
let fn = propIs(String)('name');
fn(data); // ?
挑戰一下自己,是否能夠將 propIs()
重構成 point-free 呢 ?
其實由剛剛的 propIs()
可知,pipe()
才是最後要執行的 main function,prop()
與 is()
其實都是 parameter 的 transformer function 而已,因此可以使用 useWith()
使其 point-free。
但可惜我們第一個參數是 type,與我們用 useWith()
的 signature 不合,因此再使用 flip()
加以顛倒。
Function Composition
import { compose, prop, is, useWith } from 'ramda';
let data = {
name: 'Sam'
};
let propIs = useWith(
compose, [is, prop]
);
let fn = propIs(String)('name');
fn(data); // ?
既然能使用 pipe()
達成 pipeline,反向使用 compose()
就是 function composition 了。
而且因為 compose()
使 signature 顛倒,連 flip()
都省下來了。
Ramda
import { propIs } from 'ramda';
let data = {
name: 'Sam'
};
let fn = propIs(String)('name');
fn(data); // ?
事實上 Ramda 已經提供了 propIs()
,可直接使用。
propIs()
Type → String → Object → Boolean
直接判斷 Property 型別
Type
:要判斷的 type,為 constructor
String
:要判斷 object 的 property 名稱
Object
:data 為 object
Boolean
:回傳判斷結果
Conclusion
- 儘管不知道 Ramda 的
propIs()
,也可自行由prop()
與is()
組合出來,這正是 function composition 的威力
Reference
Ramda, propIs()
Ramda, prop()
Ramda, is()
Ramda, pipe()
Ramda, useWith()
Ramda, flip()
Ramda, compose()