0%

Node.jsでlodashのflowRightを使って関数合成をする

Clojureで関数合成が楽しくなると、Node.jsでも関数型言語っぽく使いたくなります。npmのライブラリにはUnderscore.jslodashRamdaなどあります。ググってみるとlodashが良さそうなので関数のcomposeをしてみます。

Clojureのcomp

Clojureではcompを使って簡単に関数合成ができます。

((comp str +) 8 8 8)
;;=> "24"

lodashのflowRight

lodashUnderscore.js互換のライブラリでより多機能になっています。flowRightを使って関数合成ができます。_.backflow_.composeのエイリアスがついているので個人的に好きな_.composeを使います。

ちょうどtwitCommander.jsを使ってTwitter検索ツールを開発しているところなので、取得したTweetのデータを標準出力するところで使ってみます。lodashのバージョンは3.9.3です。以下はCommander.jsのコマンド処理のコードの抜粋です。

~/node_apps/node-tweet/commands/search.js

function prettyJson(data){
return JSON.stringify(data,null,2);
}

function extractData(s) {
return {
id: s.id_str,
url: createUrl(s.user.screen_name,s.id_str),
created_at: formatDate(s.created_at),
name: s.user.name,
screen_name: s.user.screen_name,
user_url: s.user.url || '',
text: s.text,
source: s.source,
expanded_url: _.get(s,'entities.urls[0].expanded_url','')
}
}

function prettyPrint(csv) {
return _.compose(console.log,
csv ? json2csv.convert : prettyJson,
_.map);
}

function commandQuery (query,count,options) {
connect()
.get('search/tweets',
{ q: util.format('%s lang:ja',query),
count: count ? parseInt(count) : 10 },
function(err, data, response) {
if (err) return console.log(err);
prettyPrint(options.csv)(data.statuses, extractData);
});
}

関数合成に関係ないコードもありますが、_.composeはprettyPrint関数で使っています。

function prettyPrint(csv) {
return _.compose(console.log,
csv ? json2csv.convert : prettyJson,
_.map);
}

flowRightはClojureのcompと同様に右側から順番に関数を評価する新しい関数を生成します。この例では_.mapでextractData関数をあててJSONを整形してから、CSVオプションが引数にある場合はnice-json2csvを使ってCSV文字列に変換します。そうでなければ2タブでstringifyします。最後にconsole.logを実行して標準出力しています。CSVフラグのように関数合成の途中で三項演算子も式として使えます。