std.bind for D2.0 (3)
http://www.kmonos.net/alang/d/phobos/std_bind.html
仕様を読み直したら,関数合成のことを全然理解していなかったことに気が付いたw
上の方のコードで「何をどういう風に実行するようになるんだろこれ・・・」とか不思議に思ったけどそこでスルーしてしまった.
関数合成っていうのはこういうことだ.
import std.stdio, std.bind; void main() { int foo(int i) {return i*2;} int bar(int i) {return i*3;} auto fooBar = bind(&foo, bind(&bar, _0)); writefln(fooBar(5)); // print:30 }
なんだ,ちゃんと動くじゃないか!
あと,__traits の代わりに isBoundFunc テンプレートを使ってみたら動いたので,そっちに書き換えた.
前は動かなかったから __traits を使ったのだが・・・何か他の条件が違ったんだろう.
そんな完成版の std.bind はこちら.
--- ~bind.d Wed Oct 03 20:38:22 2007 +++ bind.d Thu Oct 04 19:24:42 2007 @@ -263,7 +263,7 @@ } - char[] toString() { + string toString() { return "()"; } } @@ -310,13 +310,14 @@ static assert (i <= Params.length); static if (is(typeof(fn(params[0..i])))) { - const int res = i; + const int res_ = i; } else { - alias loop!(i+1).res res; + const int res_ = loop!(i+1).res_; } } - alias loop!().res res; + mixin loop!(); + alias res_ res; } /** Finds the minimal number of arguments a given function needs to be provided @@ -657,7 +658,7 @@ bind(&foo, tuple(23, 45)) --- */ -typeof(new BoundFunc!(FT, NullAlias, Tuple!(ArgList))) bind(FT, ArgList...)(FT fp, ArgList args) { +typeof(new BoundFunc!(FT, EmptySlot, Tuple!(ArgList))) bind(FT, ArgList...)(FT fp, ArgList args) { auto res = new DerefFunc!(ReturnType!(bind)); res.fp = fp; extractBoundArgs!(0, 0, ArgList)(res.boundArgs, args); @@ -665,6 +666,7 @@ } + /** bindAlias() is similar to bind(), but it's more powerful. Use bindAlias() rather than bind() where possible. <br/> @@ -690,13 +692,26 @@ Note: there is no bind-time check for reference nullness, there is however a call-time check on all references which can be disabled by using version=BindNoNullCheck or compiling in release mode. */ -template bindAlias(alias FT) { - typeof(new BoundFunc!(typeof(&FT), FT, Tuple!(ArgList))) bindAlias(ArgList...)(ArgList args) { - auto res = new DerefFunc!(ReturnType!(bindAlias)); - res.fp = &FT; - extractBoundArgs!(0, 0, ArgList)(res.boundArgs, args); - return res; - } +template bindAlias(alias FT) +{ + static if (isBoundFunc!(typeof(FT))) + { + typeof(new BoundFunc!(typeof(&(FT.func)), FT.func, Tuple!(ArgList))) bindAlias(ArgList...)(ArgList args) { + auto res = new DerefFunc!(ReturnType!(bindAlias)); + res.fp = &(FT.func); + extractBoundArgs!(0, 0, ArgList)(res.boundArgs, args); + return res; + } + } + else + { + typeof(new BoundFunc!(typeof(&FT), FT, Tuple!(ArgList))) bindAlias(ArgList...)(ArgList args) { + auto res = new DerefFunc!(ReturnType!(bindAlias)); + res.fp = &FT; + extractBoundArgs!(0, 0, ArgList)(res.boundArgs, args); + return res; + } + } }
これをMLに投げたら,いつかきっとマージしてくれるだろうか・・・.
これもスルーされたらぐれてやる(ノД`)