関数だけで論理演算をやってみた
ビット演算や演算子を使わずに関数のみの論理演算
前回は、JavaScript を使って、True 関数とFalse 関数を作りましたので、今回はAnd 関数などを作っていきます。ビット演算子などは使わずに、関数だけで、論理の演算をやってみましょう。
まずは、前回「JavaScriptの関数だけで、データ構造を書いたみた」のおさらいから。
真偽値として、True 関数とFalse 関数
前回では、次のようなコードを書きました。
var True = function (t) { return function (f) { return t; }; }; var False = function (t) { return function (f) { return f; }; };
この二つの関数、True 関数と、False 関数を、真偽値のtrueとfalseの代わりに使って、条件分岐をするところまでやりましたね。
論理積
さて、「a、かつ、b」をJavaScriptで書きたいときには、&&を使って「a && b」と書いていましたが、関数で書き直すとどうなるのでしょうか。
最初に、And 関数を書いてみましょう。
var And = function (p) { return function (q) { return p(q)(p); }; };
使い方は、And (True) (True)のように使います。「True、かつ、True」はTrueなので、True 関数とTrue 関数の二つを連続で入力したときにはTrue 関数が返されます。
また、同様に、少なくとも一方にFalse が入っていますと、次のようになります。
And(True)(True); // True And(True)(False); // False And(False)(True); // False And(False)(False); // False
論理和
続けて、論理和も同じようにコードを書きます。この論理和は「A、または、B」という意味で、JavaScriptを書いている方は「A || B」で通じるでしょう。
Or = function (p) { return function (q) { return p(p)(q); }; };
また、このOr関数の使い方も、And関数のように、二つの真偽値関数を入れていきます。
Or(True)(True); // True Or(True)(False); // True Or(False)(True); // True Or(False)(False); // False
否定
JavaScriptだと、!を頭につけるような、否定は次のようになります。
var Not = function (p) { return p(False)(True); };
反転という言葉のほうがしっくり来ます。
Not(True); // False Not(False); // True
次は、このNot 関数を使って、Xor 関数を実装します。
排他的論理和
排他的とはどちらか一方しか選ぶことができないと言う意味です。「Aなのか、Bなのか、どちらか一つ」となります。
var Xor = function (p) { return function (q) { return p(Not(q))(q); }; };
それで、下の使い方を見てください。
Xor(True)(True); //False Xor(True)(False); //True Xor(False)(True); //True Xor(False)(False); //False
False とFalse のときは、False と偽になっています。両方、真だったり、両方が偽だったりすると、False(偽)になる点にご注意ください。
あとがき
今回は、論理演算をやってみました。こうなると、数値の比較も関数だけでやってみたい気持ちがありますので、機会があれば、いずれ、関数のみの、数値の四則演算もやります。
あと、コードについては、すべて、http://jwodder.freeshell.org/lambda.htmlのメモを参照しています。