« [C#]条件分岐を使わない方法3 | トップページ | [C#]デザインパターン再考 Chain of Responsibility Pattern »

カリー化が分かるようで、分からない

関数型の資料を読んでいると、カリー化という話が出てくる。
いろいろ調べてもよく分からなかったが、ここの最後の方を読んで理解できた気がする。
部分適用との違いを明確にすることで、カリー化が分かったという感じ。

C#で書くと、こんな感じかな。

            Func<int, int, int, bool> f = (x, y, z) => x + y == z;
            Func<int, Func<int, int, bool>> g = (x) => (y, z) => x + y == z;

            Console.WriteLine("f(1,2,3) is {0}", f(1, 2, 3));
            Console.WriteLine("g(1)(2,3) is {0}", g(1)(2, 3));

ここで、gはfのカリー化された関数ってことになるのだと思う。自信はないけど。
部分適用っていうのは、たぶんg(1)のことなんだろうな。一部の引数に具体的な数値を適用して、残りの引数による関数を作るってことなんだろう。

で、ここからが分からない。なぜカリー化をするのか?

あるページによると、「カリー化のメリットは、部分適用である。ある関数を雛形として、引数をカスタマイズした関数を作り出せる」ということらしい。「高階関数と組み合わせると、その表記の簡潔さは一目瞭然となる」のだそうだ。うむぅ・・・

            var data1 = new[] { 1, 2, 3 };
            var data2 = new[] { 4, 5, 6 };

            Func<int, int, int> plus = (x, y) => x + y;
            var result1 = Enumerable.Range(0, 3).Select(i => plus(data1[i], data2[i]));
            Console.WriteLine("result1 = {0}", String.Join(", ", result1.Select(n=>n.ToString())));

            Func<int, Func<int, int>> curried_plus = (x) => (y) => x + y;
            var result2 = data1.Select(x=>curried_plus(x)).Select((plusx, i) => plusx(data2[i]));
            Console.WriteLine("result2 = {0}", String.Join(", ", result2.Select(n => n.ToString())));

うーん・・・たぶん、C#でやるのが悪いんだろうな。
後の方が分かりにくいコードになっているから。

カリー化することで、実行上(言い方が正しい?)のメリットはないのだろうか?

« [C#]条件分岐を使わない方法3 | トップページ | [C#]デザインパターン再考 Chain of Responsibility Pattern »

プログラミング」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: カリー化が分かるようで、分からない:

« [C#]条件分岐を使わない方法3 | トップページ | [C#]デザインパターン再考 Chain of Responsibility Pattern »

2019年10月
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
無料ブログはココログ