Roy による関数合成

Groovy, Scala, F#, Haskell による関数・クロージャの合成Java SE 8 で関数合成 で実施したものと同様の関数合成を Roy で試してみました。

Roy は JavaScriptコンパイルできる関数型のプログラミング言語です。

ソースは http://github.com/fits/try_samples/tree/master/blog/20140721/

はじめに

Node.js で Roy を実行するには roy を npm install するだけです。

Roy のインストール例
> npm install roy

roy@0.2.2 node_modules\roy
├── unicode-categories@0.9.1
├── underscore@1.2.0
├── source-map@0.1.8 (amdefine@0.1.0)
└── escodegen@0.0.22 (estraverse@0.0.4, esprima@1.0.4)

これでカレントディレクトリの node_modules へ roy がインストールされました。

Underscore.js を使った関数合成

Roy で関数合成を行うには Underscore.js の compose を使えばよいようです。 (roy/lib/prelude.roy に compose 関数が定義されているもののコメントアウトされているため)

sample.roy
let _ = require 'underscore'

let plus n = n + 3
let times n = n * 2

let f1 = _.compose times plus
let f2 = _.compose plus times

// times(plus(4)) = 14
console.log(f1 4)
// plus(times(4)) = 11
console.log(f2 4)

Roy のスクリプトファイルを直接実行するには -r オプションを指定して実行します。

実行結果
> roy -r sample.roy

14
11

オプションを指定せずに実行すると Roy スクリプトJavaScriptコンパイルし、.js ファイルが生成されます。

コンパイル実行例
> roy sample.roy
sample.js (生成されたファイル)
var _ = require('underscore');
var plus = function (n) {
    return n + 3;
};
var times = function (n) {
    return n * 2;
};
var f1 = _.compose(times, plus);
var f2 = _.compose(plus, times);
// times(plus(4)) = 14
console.log(f1(4));
// plus(times(4)) = 11
console.log(f2(4));//@ sourceMappingURL=sample.js.map

自前で compose 関数を定義して関数合成

Underscore.js の代わりに compose 関数を自前で定義するのも簡単です。

sample2.roy
let plus n = n + 3
let times n = n * 2

let compose f g = \x -> f (g x)

let f1 = compose times plus
let f2 = compose plus times

// times(plus(4)) = 14
console.log(f1 4)
// plus(times(4)) = 11
console.log(f2 4)
実行結果
> roy -r sample2.roy

14
11