Clojureで関数合成が楽しくなると、Node.jsでも関数型言語っぽく使いたくなります。npmのライブラリにはUnderscore.js、lodash、Ramdaなどあります。ググってみるとlodashが良さそうなので関数のcomposeをしてみます。
Clojureのcomp
Clojureではcompを使って簡単に関数合成ができます。
lodashのflowRight
lodashUnderscore.js互換のライブラリでより多機能になっています。flowRightを使って関数合成ができます。_.backflow
と_.compose
のエイリアスがついているので個人的に好きな_.compose
を使います。
ちょうどtwitとCommander.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フラグのように関数合成の途中で三項演算子も式として使えます。