このファイルコンパイルすると、コンパイルが終わりません!コンパイラが無限ループするっていったいぜんたい。
http://shinh.skr.jp/tmp/functional_endless.d
それはともかく。
http://d.hatena.ne.jp/niha/20061209#1165682303
謎を色々追うにはさんに感動して色々ほげほげしていたところ、 delegate 通りました。「そういえばfuncptrとかあるしdelegateがaliasで渡されたらfunctionに…って出来ないかな」というにはさんの発言をそのまま実装しただけですが。
まぁ皮かぶせてるだけでかっこ悪いので、できればそのまま呼べるようにして下さい。
import std.typetuple; import std.traits; import std.stdio; class Functional_(alias func, int n = 0){ static: alias ReturnType!(func) Ret; alias ParameterTypeTuple!(func)[0..n] preArgs; alias ParameterTypeTuple!(func)[n..$] Args; ReturnType!(f!(T)) opCall(T...)(T t){ return f!(T)(t); } template f(T...){ static assert(ArgsCheck!(Args.length, Args, T), "bad parameter error"); static if (is(T == Args)){ Ret f(Args args){ return func(args_, args); } } else { Functional_!(func, T.length) f(T t){ return new Functional_!(func, T.length)(t); } } } this(preArgs args){ foreach(i,x; args){ args_[i] = x; } } private: preArgs args_; template ArgsCheck(int n, T...){ static if (is(T[0..n] == T[n..$])){ const ArgsCheck = true; } else static if (n == 0){ const ArgsCheck = false; } else { const ArgsCheck = ArgsCheck!(n-1, T[0..n-1], T[n..$]); } } } template Functional(alias func) { static if (is (typeof(func) == delegate)) { alias Functional_!(function ReturnType!(func) (ParameterTypeTuple!(func) a) { return func(a); }) Functional; } else { alias Functional_!(func) Functional; } } int f(int x, int y){ // 普通の関数宣言 return x + y; } Functional!(f) func; // 新スタイルの関数宣言! Functional!((int x, int y){ return x + y; }) funcd; Functional!(function int (int x, int y){ return x + y; }) funcf; void main(){ writefln(func(3,4)); // 7 auto x = func(4); writefln(x(2)); // 6 writefln(func(1)(6)); // 5 writefln(funcd(3, 4)); auto fd = funcd(2); writefln(fd(1)); writefln(funcf(7, 10)); auto ff = funcf(2); writefln(ff(7)); }