折角なので函数ポインタでコンビネータっぽいものを実装してみようかと思います。
今回実装するのはLazy Kなどでも採用されているSKIコンビネータと呼ばれるものです。
コンビネータについて:
翻訳:コンビネータ論理チュートリアル
Lazy K(wikipedia)
要は函数S,K,Iを実装するだけです(コンビネータの妥当性はコンパイルエラーでキャッチできるはずなので割愛します)
函数Iは恒等写像ですから来た変数をそのまま返します(I(x){return x;})
Kは2つの引数を取り前だけを返します(K(x,y){return x;})
Sは少し複雑で、引数xyzが来たらxにyと(x z)を適用させます(S(x,y,z){return x(y,(x,z))})
ここで言う引数とは、函数(というかラムダ式)を含んでいます
これをそのままCで実装してみます
#include
void* I(void* x){
return x;
}
void* K(void* x, void* y){
return x;
}
void* S(void* (*x)(void*, void*), void* (*y)(void*), void* z){
return (*x)(z, (*y)(z));
}
void dummy(void){}
void out(int a){ printf("here!:%d",a); }
int main(void)
{
// SKK = I
void (*f)(int) = S(K,K,out);
(*f)(10);
return 0;
}
実行結果は
が出力され、確かにout函数が実行されていることが分かりますhere!:10
以上、函数ポインタを用いたSKIコンビネータの実装でした〜☆
(どうせならチャーチ数も実装して、自然数の足し算とか出来るようにさせれば、例えばですが函数fを2回作用させる、みたいな処理も出来るようになって素敵なのでやってみようかと思っています)