えーと
- 関数テンプレートの戻り値型推論ができるようになったので
- 前に取り組んでいたstd.bindを簡単に直せるようになってないかなと思って
- そのすぐ後にそういえばずっと前にstd.functionalってのが増えてたなと思い出して
- 早速中身を見てみたら
- std.bindもういらねーじゃん
となった.
ここをベースにサンプルコードを書いてお勉強.
import std.functional : unaryFun, binaryFun, adjoin, compose, pipe; import std.typecons : Tuple; import std.conv : to; import std.algorithm : map; import std.string : split; void main() { // // 文字列から1引数の関数を作る // alias unaryFun!("(a & 1) == 0") isEven; bool x = isEven(1); bool y = isEven(2); assert(x == false && y == true); // // 文字列から2引数の関数を作る // alias binaryFun!("a < b") less; bool t = less(1, 2); bool u = less(2, 1); assert(t == true && u == false); // 引数を文字列で渡すこともできるみたい alias binaryFun!("a > b") greater; bool v = greater("1", "2"); bool w = greater("2", "1"); assert(v == false && w == true); // // 関数を並列に結合 // static bool f1(int a) { return a != 0; } static int f2(int a) { return a / 2; } Tuple!(bool,int) z = adjoin!(f1, f2)(5); // 結果はTupleになってる assert(z._0 == true && z._1 == 2); // // 関数合成1(直列に連結) // // ただしstd.functionalの306行を次のように書き換えないと動かなかった(dmd2.015にて) // auto doIt(E)(E a)//typeof({ E a; return fun0(fun1(a)); }()) doIt(E)(E a) int[] a = compose!(map!(to!(int)), split)("1 2 3"); assert(a == [1,2,3]); // // 関数合成2(関数合成1の逆順に関数が呼ばれる) // int[] b = pipe!(split, map!(to!(int)))("4 5 6"); assert(b == [4,5,6]); }
コード中に書いているように,std.functionalの306行を
typeof({ E a; return fun0(fun1(a)); }()) doIt(E)(E a)
から
auto doIt(E)(E a)
に書き換えないとstd.functional.composeが動かないので注意.
件の戻り値型が大いに役だった.
追記
あ,関数合成はできるけど引数にリテラルをbindできないのかこれ?
じゃあbindいらなくないじゃん・・・.