関数だけで四則演算をやってみた (前編)
四則演算について
今回の記事では、小学校で習った算数を思い出しながら、単純な四則計算をJavaScriptのコードで書いていきたいと思います。もちろん、+や-などの演算子を使わず、関数だけで実装します。
数値の関数
まず、準備として、0、1、2、3...の数字(自然数)を、関数として表現します。
var _0 = function (f) { return function (x) { return x; }; }, _1 = function(f) { return function(x) { return f(x); }; }, _2 = function(f) { return function(x) { return f(f(x)); }; };
_0関数は、数字の0に当たります。同様に、_ (アンダーバー)を対応する数字の頭につけて、数値の関数ができます。
ToNumber関数
このままだと、console.logでログ出力するときに関数のままだと、困ります。たとえば、console.log(_0)の返り値は、function(f) {...}となりかねません。
そこで、関数を数値に変換するToNumber関数を、前もって、作っておきましょう。
/*関数をJavaScriptの数値オブジェクトに変換*/ var ToNumber = function (f) { return f( function (x) { return x + 1; } ) (0); }
このToNumber関数を使えば、以下のように、数値出力もできるようになります。
ToNumber (_0)); // 0 ToNumber (_1)); // 1 ToNumber (_2)); // 2
後者関数
足し算のコードを書く前に、後者関数について説明しておきましょう。Successor関数は、引数に1を足して返す関数です。これを「後者関数」と呼びます。
/*後続関数 引数numに対して、num+1を返す(ただし、関数)*/ var Successor = function(num) { return function(f) { return function(x) { return f( num(f)(x) ); }; }; };
この関数の使い方はかんたんです。さきほど作った数値関数を_0、_1などを引数に入力するだけでOKです。
ToNumber(Successor(_0)); //1 ToNumber(Successor(_1)); //2 ToNumber(Successor(Successor(_0))); //2
続けて、この後者関数を使って、足し算をやっていきましょう。
加法演算
単なる足し算ができるプラス関数を作ります。
var Plus = function (m) { return function (n) { return n(Successor)(m); }; };
プラス関数は、後者関数を何度も呼び出すことで、数を次々と、足していくことができます。たとえば、_2(Successor)ならば、次のような形で呼び出されるでしょう。
function (x) { /*Successor関数が二度、呼び出されている*/ return Successor( Successor(x) ); }
ですから、このPlus関数は、次のようにして、二つの数値関数の足し算ができます。
ToNumber(Plus(_0)(_1)); //1 ToNumber(Plus(_1)(_2)); //3 ToNumber(Plus(_2)(_2)); //4
同じようにして、今度は引き算をやってみましょう。
減法演算
前者関数
さきほどの後者関数とは逆に、-1ができる前者関数を前もって作っておきます。
/*前者関数 引数numに対して、num-1を返す。numが0のときは0を返す(ただし、関数)*/ var Predecessor = function (num) { return function (f) { return function (x) { return num ( function (g) { return function (h) { return h(g(f)); }; } ) ( function (u) { return x; } ) ( function (u) { return u; } ); }; }; }; /*使い方のサンプル*/ ToNumber(Predecessor(_0)); //0 ToNumber(Predecessor(_1)); //0 ToNumber(Predecessor(Predecessor(_2))); //0
今度は引き算ができるマイナス関数として、Minus関数を書きます。
var Minus = function (m) { return function(n) { return n(Predecessor)(m); }; };
使い方はPlus関数と同じです。
ToNumber(Minus(_0)(_1)); //0 ToNumber(Minus(_2)(_1)); //1 ToNumber(Minus(_2)(_0)); //2
後編に続く
続きは次回の後編で書きます。次回は、関数だけで積を求めてみましょう。次回「関数だけで四則演算をやってみた (後編)」