ラムダ式で再帰表現を書いてみました


こんにちは、こだかです。

今回は、さあできること開発者セミナーのツアー中で出た話題
「ラムダ式で再帰表現を書いてみよう!」を書きたいと思います。

ラムダ式の元は関数言語からきていますので、考え方としては、再起表現はぴったり当てはまります。

例えば、指定された整数の和(n + n-1 + n-2 +...+1)を求める関数を定義してみます。

Func<int,int> func = null;
func = x => x < 1 ? 0 : x + func(x - 1);

ちょっと見慣れないかもしれないですね。
Func<int,int>は引数と戻り値がともにintである関数funcを宣言しています。
次にfuncの実装を行っており、「funcは引数xが1より小さかったら0、そうでない場合は x + f(x-1)を計算する」ことを表現したものです。 そうして、引数xの値が0になるまで、繰り返しの計算を行います。

呼び出してみます。ためしに1から10までの和を求めてみます。

MessageBox.Show(func(10).ToString());

結果は当然55になります。何となく、ご理解頂けるでしょうか?

では、これだけだと面白くないので、今度はI/Oを伴ったモノにしてみます。
例としては、そうですねSinカーブの描画を行ってみたいとおもいます。

private void button1_Click(object sender, EventArgs e)
{
    pictureBox1.Image = null;
    Bitmap bitmap = new Bitmap(810, 300);
    double x = 0;

    Func<Bitmap, double, Bitmap> func = null;
    func = (bm, x1) => (SetPixel(bm, (int)x1, (int)(200 / 2 * (1 - (float)Math.Sin(x1 * 2 * Math.PI / (800 - 1))))) > 800) ? bm : func(bm, x1 + 1);
    pictureBox1.Image = func(bitmap, x);
}

public int SetPixel(Bitmap b, int x, int y)
{
    b.SetPixel(x, y, Color.Red);
    return x;
}

できましたけど、なんだか美しくないですね。(Sinカーブ描画用の座標位置の計算がごちゃごちゃしている点はおいたとしても、SetPixelを新たに定義しているところなんか最悪です。)
この辺関数言語なら、スッキリ治まるのですが・・・C#でもっと良い方法があったらフィードバックお願いします。

実行結果です。
 image

こだかたろう

Comments (3)
  1. Nori says:

    久しぶりに拝見させていただきました。

    こだかさんのブログはわかりやすくてイイですね。

    ここで唐突に質問です。

    実は、職場でVS2008Proを導入しWEB開発をしていますが、

    一つ困ったことが起きています。

    すごく単純なことなんですが、WEBのデザイナ上で

    コントロールを複数選択出来ないんですけど・・・

    これはなんの罠なんでしょうか?Googleで検索しても

    あまりいい答えはヒットしないので、質問させていただきました。

    もし情報がありましたら教えてください。

  2. j.sakamoto says:

    ラムダ式で再帰、待っておりました。

    なるほど、変数(関数のリファレンス)を先に用意しておいて、この変数を参照する形でラムダ式を定義することで、結果、再帰の輪が完成するわけですね。

    ラムダ式で再帰、どうやってやるんだろう? とずっと考えておりましたが、これでスッキリです。

  3. Taro Kodaka says:

    Nori さん

    コメントありがとうございます。

    >コントロールを複数選択出来ないんですけど・・・

    うぅ・・・確かに・・・ぐはっ。

    ちょっと確認してみます。なにかわかり次第ご報告いたします。

    j.sakamotoさん

    本当は、質問を受けたタイミングですぐにお答えすればよかったのですけど、

    アルコールが頭に回って(全然飲めないんです・・・)無理でした。

    そこで、さぁでき@名古屋に移動するため、新幹線に乗りながら書いたのが、今回の記事です。

    また、お会いしたときは、色々勉強させてください。よろしくお願いします。

Comments are closed.

Skip to main content