2010年10月11日
C#でunfold
T_GYOUTENさんの記事
に触発されて、C#で3つのUnfold関数を書いてみました。
名前をどうしようか迷ったのですが、Unfoldクラスを定義し、そこに Do メソッドを定義
することにしました。一つの機能しかないstaticクラスを作る時には、名前をどうするか
悩みますね。
引数の順番は、F#とは逆にし、初期値, generator の順にしました。
まずは、一つ目のバージョンのUnfold.Doメソッド
使い方はこんな感じ。
true, false が繰り返されます。
generatorが null を返すと終了しますが、Tが値型の場合、nullがとれないので、
無限に繰り返すことになります。
2つめは、繰り返し条件を指定できるバージョン。これならば、値型でも有限のシーケンスを 得ることが できます。
使い方です。
1 2 4 8 16 32 64 128 256 512 と表示されます。
最後は、最も汎用性のあるバージョンで、F#のSeq.unfoldとほぼ同等のものです。
Tupleを使っているので、ちょっと分かりにくいかもしれませんが、
これだと、初期値に与える型と、戻り値の各要素の型を別のものにすることができます。
以下、使い方の例です。
true, false を繰り返しています。 これだと、最初に示した true, false を返すコードのほうが簡単なので、
このTuple使ったDoメソッドだからできる例を示します。
フィボナッチ数列を求めるコードです。
unfoldは強力ですが、使うにはちょっと慣れが必要ですね。
名前をどうしようか迷ったのですが、Unfoldクラスを定義し、そこに Do メソッドを定義
することにしました。一つの機能しかないstaticクラスを作る時には、名前をどうするか
悩みますね。
引数の順番は、F#とは逆にし、初期値, generator の順にしました。
まずは、一つ目のバージョンのUnfold.Doメソッド
使い方はこんな感じ。
true, false が繰り返されます。
generatorが null を返すと終了しますが、Tが値型の場合、nullがとれないので、
無限に繰り返すことになります。
2つめは、繰り返し条件を指定できるバージョン。これならば、値型でも有限のシーケンスを 得ることが できます。
使い方です。
1 2 4 8 16 32 64 128 256 512 と表示されます。
最後は、最も汎用性のあるバージョンで、F#のSeq.unfoldとほぼ同等のものです。
Tupleを使っているので、ちょっと分かりにくいかもしれませんが、
これだと、初期値に与える型と、戻り値の各要素の型を別のものにすることができます。
以下、使い方の例です。
true, false を繰り返しています。 これだと、最初に示した true, false を返すコードのほうが簡単なので、
このTuple使ったDoメソッドだからできる例を示します。
フィボナッチ数列を求めるコードです。
unfoldは強力ですが、使うにはちょっと慣れが必要ですね。
2010年10月07日
指定した複数の値を繰り返す
前回の記事の続きです。
前回示した false true を繰り返す以下のコードは、bool型しか扱えないので、使い道が限られています。
任意の型にも対応させれば、使い道がありそうです。
ジェネリックスの出番ですね。
というクラスを作れば、
とか、
とか、いろいろ使えます。
foreach も使いたいということであれば、以下のようにGetEnumerable メソッドを追加します。
そうすれば、
なんて、書けますね。
ここまで書くと、別に要素が2つに限定することもないなーということで、
シーケンスを受け取る拡張メソッドを書いてみました。
これを使うコード例を以下に示します。
これだと、foreachでしか使えないんじゃないのと思う人もいると思いますが、いえいえ、次のような書き方もできます。
でも、使い勝手は良くないです。ラムダ式を返す部分をメソッドにしてしまったほうが良いかもしれません。
興味のある方は、EnumerableExtentions クラスにメソッドを追加してみてください。
前回示した false true を繰り返す以下のコードは、bool型しか扱えないので、使い道が限られています。
任意の型にも対応させれば、使い道がありそうです。
ジェネリックスの出番ですね。
というクラスを作れば、
とか、
とか、いろいろ使えます。
foreach も使いたいということであれば、以下のようにGetEnumerable メソッドを追加します。
そうすれば、
なんて、書けますね。
ここまで書くと、別に要素が2つに限定することもないなーということで、
シーケンスを受け取る拡張メソッドを書いてみました。
これを使うコード例を以下に示します。
これだと、foreachでしか使えないんじゃないのと思う人もいると思いますが、いえいえ、次のような書き方もできます。
でも、使い勝手は良くないです。ラムダ式を返す部分をメソッドにしてしまったほうが良いかもしれません。
興味のある方は、EnumerableExtentions クラスにメソッドを追加してみてください。



