Hatena::ブログ(Diary)

当面C#と.NETな記録 このページをアンテナに追加 RSSフィード

2006/12/4 (月)

[] Moreコマンド  Moreコマンドを含むブックマーク  Moreコマンドのブックマークコメント

パイプラインパターンで一時蓄積してみました。

外側のforeachループ一回ごとにMoreの中(右)では10回回ります。

まだちょっと荒削りというか、未熟だけど。

        static void Main()
        {
            try
            {
                string fileName = "../../Program.cs";

                foreach ( string str in More( 10, AddCount( TextFileReader( fileName ) ) ) )
                {
                    Console.WriteLine( str );
                    Console.WriteLine( "--more--" );
                    Console.ReadLine();
                }
            }
            catch ( Exception e )
            {
                Console.WriteLine( e.Message );
            }
            Console.ReadLine();
        }

        static IEnumerable<string> More( int count, IEnumerable<string> input )
        {
            if ( count <= 0 ) throw new ArgumentException( "countは1以上にしてください", "count" );

            StringBuilder sb = new StringBuilder();

            int n = count;
            foreach ( string s in input )
            {
                sb.AppendLine( s );
                n--;

                if ( n <= 0 )
                {
                    yield return sb.ToString();
                    sb.Remove( 0, sb.Length );
                    n = count;
                }
            }

            if ( 0 < sb.Length )
                yield return sb.ToString();
        }

        static IEnumerable<string> AddCount( IEnumerable<string> input )
        {
            int count = 1;

            foreach ( string s in input )
            {
                yield return count + " : " + s;
                count++;
            }
        }

        static IEnumerable<string> TextFileReader( string fileName )
        {
            using ( StreamReader sr = new StreamReader( fileName ) )
            {
                string line;
                while ( ( line = sr.ReadLine() ) != null )
                    yield return line;
            }
        }

#事情によりしばらく書けません。

トラックバック - http://d.hatena.ne.jp/siokoshou/20061204

2006/12/2 (土)

[] パイプラインパターンでテキスト処理  パイプラインパターンでテキスト処理を含むブックマーク  パイプラインパターンでテキスト処理のブックマークコメント

パイプラインパターンで、ちょっとだけ実用的な例を。

ログなんかをPerlRubyで処理して必要な部分を抜き出したりなんてことをよくやると思いますが、PerlやRubyではファイルを開いて一行ずつ処理するのが超簡単です。パイプラインパターンを使えば、同様に簡単にできるので、実演してみました。

Mapに渡したdelegateで行番号をつけて、Takeで先頭10行だけ抜き出しています。

        static void Main()
        {
            try
            {
                int lineCount = 0;

                foreach ( string str in Take( 10, Map<string, string>( delegate( string s )
                        { return ++lineCount + " : " + s; },
                    TextFileReader( "../../Program.cs" ) ) ) )
                {
                    Console.WriteLine( str );
                }
            }
            catch ( Exception e )
            {
                Console.WriteLine( e.Message );
            }

            Console.Read();
        }

        static IEnumerable<string> TextFileReader( string fileName )
        {
            using ( StreamReader sr = new StreamReader( fileName ) )
            {
                string line;
                while ( ( line = sr.ReadLine() ) != null )
                    yield return line;
            }
        }

        static IEnumerable<S> Map<T, S>( Converter<T, S> converter, IEnumerable<T> input )
        {
            foreach ( T var in input )
                yield return converter( var );
        }

        static IEnumerable<T> Take<T>( int count, IEnumerable<T> input )
        {
            if ( 0 < count )
            {
                foreach ( T ele in input )
                {
                    yield return ele;
                    count--;
                    if ( count <= 0 )
                        break;
                }
            }
        }

わかりますかね?もうC#に見えないかもw

サンプルでは全部パイプラインにつないでいますが、無理に繋げず、foreachのループの中で処理してもいいですね。

フィルタかけたり、Mapで各行に何か処理したりといったあたりが楽にできます。

まぁ、ログ処理だとクイックハックできないコンパイル言語の出番は少ないですけど。

トラックバック - http://d.hatena.ne.jp/siokoshou/20061202

2006/12/1 (金)

[] 列挙子スゴス  列挙子スゴスを含むブックマーク  列挙子スゴスのブックマークコメント

コメントにも書きましたが、LINQ落としてみました。VisualStudioにパッチが当たっているとインストールできないようで、SP1β(だったような気がする)を消したくないので、MSIをほどいて中を見てみました。

Docsの下にSequence.csを見つけて、これがまさに関数言語なライブラリでびっくりです。昨日の予測はまさにあたっていたようで、IEnumerable<T>(以下、列挙子)がLINQの基礎になっていました。

後からずいぶん古いこの記事の真ん中あたりに、ズバリ「IEnumerable<string>」って書いてあるのを見つけたんですけどね!

列挙をまるでプロトコルのように使って、単機能のメソッドを数珠繋ぎにして処理していくって流れのようです。

高階関数のように関数を引数に取ってるわけじゃなくて、処理結果の値を順番に取って処理しているわけだから、UNIXコマンドラインのパイプのようなイメージですかね。

ん〜、でも関数を引数に取っていないというと、うそになるか…。Predicate<T>みたいな判断するデリゲートは取ります。

入力と出力を列挙子に揃えることで、単機能の処理であっても使い回しが利くし、処理を書くのもテストするのも簡単になります。って書くと、その利点はまさに関数型言語ですね。

C++STLイテレータを介してコンテナとアルゴリズムを繋いで関数型言語っぽいことをやってみせたように、C#では(イテレータの機能限定版の)列挙子を使ってコンテナとアルゴリズムを繋いでみせてくれます。

STLから隔世遺伝した遺伝子が、今目覚めたって感じでしょうかw

[][] IEnumerable<T>とHaskellのリストを比較してみる  IEnumerable<T>とHaskellのリストを比較してみるを含むブックマーク  IEnumerable<T>とHaskellのリストを比較してみるのブックマークコメント

入門Haskellの3章リストから、Haskellのリストの特徴を引用してみます。

・リストは任意長のデータの連なりである

・リストは「先頭要素」と「残り」に分けられる

・1つのリストに含まれるデータはすべて同じ型を持つ

IEnumerable<T>の特徴と一致しています。

さらに3.5無限リストより引用。

無限のリストは、実際には次々と順番に要素の値を計算しているというリストです。このため遅延リスト(lazy list)と呼ばれることもあります。また、ストリーム(stream)と呼ばれることもあります。

id:siokoshou:20061130で詳細に眺めた特徴と一致しています。まさにIEnumerable<T>ですね。

う〜ん、気付かなかった。

NyaRuRuNyaRuRu 2006/12/02 02:43 LINQ については一応登場後にこういう感じで解説しています.
http://d.hatena.ne.jp/NyaRuRu/20050921
http://d.hatena.ne.jp/NyaRuRu/20051017
http://d.hatena.ne.jp/NyaRuRu/20060223

んで,その後 DLINQ が魔法になり,
http://blogs.msdn.com/daigoh/archive/2006/04/17/577975.aspx

さらに ADO とのごにょごにょがあって今に至る,という感じですかねぇ.
ごにょごにょ以降については私もまだ知らないです.

siokoshousiokoshou 2006/12/02 08:00 おぉ、勉強になります!ありがとうございます。
Pipeline Patternとして既に名前が付いていたんですね。以前、「IEnumerable<T>」を隠したいなと思って「using Pipe = IEnumerable<T>;」って書いてコンパイラに怒られましたw そかそか、ごめんごめん(^^;って謝りました…

気になるのはやはり最適化ですよね。メソッド間を越えてかなり積極的に最適化してくれないと性能が問題になりそうで。

メソッド拡張いいですね!StringBuilderのAppendのようにガチャガチャくっつけれるのは便利そう。

DLINQってSQLを組み立てて投げるんですね。IEnumerable<T>ばかり見てたのでまさかメモリに取り込まないよね?と疑問に思ってましたw
しかし、Expression Treeって…。つまりLISPなのかな、とよく分からないけど書いてしまう…。

NyaRuRuNyaRuRu 2006/12/02 21:00 >LINQ と Haskell
LINQ には Haskell 界でも有名な Erik Meijer 氏が絡んでいるのですが,このあたりで「最も重要な点として monad comprehensions のコンセプトを持ち込んだよ」と強調されてますね.
http://lambda-the-ultimate.org/node/1253
この辺りもおもしろいです.
http://research.microsoft.com/~emeijer/Papers/OOPSLA2005.ppt

siokoshousiokoshou 2006/12/02 23:19 う〜ん、私には not easily comprehensible ですw
Erik Meijer氏はすごい方のようですね。なによりすごいのは、裏側の仕組みはよくわからなくても、DLINQは誰でも簡単に使えそうってのがすごいです。
パワポ資料がかわいいのもおちゃめで、いいw

トラックバック - http://d.hatena.ne.jp/siokoshou/20061201
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 06 | 09 | 11 | 12 |
2007 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 08 | 09 | 10 | 12 |
2009 | 01 | 03 | 04 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 07 |
2011 | 04 | 07 | 10 |
2012 | 04 | 12 |
2013 | 08 |
2014 | 03 | 08 |
2017 | 09 |