スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#によるデザインパターン入門 Iterator パターン(3) 内部イテレータ

内部イテレータとは、外部イテレータオブジェクトを生成することなく、容器内の要素に対して繰り返しユーザコードを逐一呼び出す方式です。
 
前回までであれば、for in での取り扱いが内部イテレータ方式となります。
 
内部イテレータの利点は、コード上で、わざわざ外部イテレータオブジェクトを生成することなく簡潔に表現できることです。
一方外部イテレータ方式の利点は、「ポインタを途中で止めたり、再スタートしたり、リセットしたりできる」ということと、「複数の外部イテレータを生成して、別々にポインタを進めたりできる」ということです。
 
F#においては、list,array,set等の使い勝手の良い「データの容器」が準備されているので、特に自分で内部イテレータが使えるクラスを定義する場合は少ないと思われますが、そのような必要がある場合は、IEnemerableインターフェイスを実装したクラスとして、定義すると便利です。IEnumerableインターフェイスを実装していれば、F#ではseq型として使用できるのからです。
 
では前回定義したMyArray<_>クラスを再掲します。
 
> open System
open System.Collections
open System.Collections.Generic;;
> type MyGArrIter<'a> (iter_arr : array<'a>) =
    let mutable index = -1
 
    interface IEnumerator<'a>  with
        member this.Current =
                iter_arr.[index] 
 
    interface IEnumerator with
        member this.MoveNext() =
                if index < iter_arr.Length - 1 then
                    index <- index + 1
                    true
                else
                false 
        member this.Reset() =
                index <- -1
         
        member this.Current =
                iter_arr.[index] :> obj
 
    interface IDisposable with
        member this.Dispose() =
            ()
 
type MyGArray<'a> (in_array : array<'a>) =
    interface IEnumerable<'a> with
        member this.GetEnumerator() =
            (new MyGArrIter<'a> (in_array)) :> IEnumerator<'a>
    interface IEnumerable with
        member this.GetEnumerator() =
            (new MyGArrIter<'a> (in_array)) :> IEnumerator;;
 
type MyGArrIter<'a> =
  class
    interface IDisposable
    interface IEnumerator
    interface IEnumerator<'a>
    new : iter_arr:'a array -> MyGArrIter<'a>
  end
type MyGArray<'a> =
  class
    interface IEnumerable
    interface IEnumerable<'a>
    new : in_array:'a array -> MyGArray<'a>
  end
 
インスタンスをひとつ生成しておきます。
 
> let myIntArr =   new MyGArray<int> ([|1;2;3|]);;
 
val myIntArr : MyGArray<int>
 
seq関連のメソッドをいろいろ使ってみます。
 
> Seq.iter (fun x -> printfn "%d" x ) (myIntArr :> IEnumerable<int>);;
1
2
3
val it : unit = ()
 
> Seq.map (fun x -> 2*x) (myIntArr :> IEnumerable<int>);;
val it : seq<int> = seq [2; 4; 6]
 
> Seq.fold (+) 0 (myIntArr :> IEnumerable<int>);;
val it : int = 6
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。