Haskellチュートリアルの最初あたりを見てる。こんな例があった。
add :: Integer -> Integer -> Integer add x y = x + y
ふたつの整数の和を得る関数を定義している。定義はともかくとしてその型がなぜInteger->Integer->Integerなのか?
Integer->IntegerはIntegerを引数として受け取り、Integerを返す関数の意。ということはInteger->Integer->IntegerはIntegerを引数として受け取り、Integer->Integerの関数を返す関数と解釈される。
つまり、例えば実際に「add 1 2」という風に具体的な値を与えて評価した場合には、まず「add 1」が評価されて「与えられた引数に1を足す関数」が返され、それに対して2を適用するという順序になる。
Schemeで表現すると、こんなことをやっているわけだ。
(define add (lambda(x) (lambda(y) (+ x y))))
このSchemeの場合だと評価するとき「((add 1) 2)」というように括弧で囲んで陽に評価する必要があるが、意味としては同じである。
順番に見ていくとなるほどと感心するが、ぱっと見では「なんじゃこりゃ」ってカンジで、思想の違いを思い知らされる。
と言うわけで、HaskellにもSchemeにも関心が無い人には面白くないと思うので、C++で書いてみた。要はこんなことをやってるんです。
#include <iostream> using namespace std; class add { private: int arg1; public: add(int arg1): arg1(arg1) {}; int operator()(int arg2){ return arg1+arg2; } }; int main(void) { cout << add(1)(2); return 0; }
関数型言語って要は関数オブジェクトを暗黙で作ってるってことなんだよね。