スポンサーサイト

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

F#入門第45回(OOP(10)Type Extensions(Extension methods))

今回のお題は「OOP(10)Type Extensions(Extension methods)」です。
 
まずは宿題の解答から
 
(宿題)
let t = new ResizeArray<int*float*int> ([|(1,0.1,2);(3,5.9,5);(-3,-1.1,6);(-3,2.0,-2);(2,8.5,-5)|])
 
第3成分のint型の数が昇順となるような、インスタンスを作ってtをソートしてみてください。
 
(解答)
 
let order3u = { new IComparer<int*float*int> with
                    member this.Compare(l,r) =
                      let (_,_,l3) = l 
                      let (_,_,r3) = r
                      if l3 > r3 then 1
                      elif l3 = r3 then 0
                      else -1 
                      }  
実行例
 
> t.Sort(order3u);;
val it : unit = ()
 
> t;;
val it : ResizeArray<int * float * int> =
  seq [(2, 8.5, -5); (-3, 2.0, -2); (1, 0.1, 2); (3, 5.9, 5); ...]
 
なおCompareの返り値で、並べ替える場合ですが、1、-1という値にとくに意味があるわけでなく、正か0か負かということが本質的な意味合いを持ちます。このことを使うとのBLUEPIXYさんの解答のような、簡潔なコードになります。(let束縛も一回で済ませていることにも注目)

let order3u = { new IComparer<int*float*int> with
                       member this.Compare(l,r) =
                            let ((_,_,l3),(_,_,r3)) = l,r
                            l3 - r3
                        }

さて、今回のお題のExtension methodsです。 (Type Extensionsが正式な名前になりようなので、以下Extension methodsはType Extensionsに読み替えてください。)
object expressionにより、「abstractなメソッド、プロパティを実装した、無名クラスを派生させて、そのインスタンスを返す」ことが可能になりました。
今回のExtension methodsは、既存のクラスに新しいメソッド、プロパティを追加する機構です。追加してもクラスとしてはそのままです。継承関係になるわけではありません。
また追加は自分で定義したクラス(discriminated unionも本質的にはクラスなので、これも含みます。)でも、.NET側で定義されているクラスでも可能です。
ただ、自分で定義したクラスについてはextension methodsを使うよりは、定義本体でメソッド、プロパティを定義するほうがよいかと思います。(定義がバラバラになると、扱いにくいので。)
さて、実際にExtension methodsを使うときの構文は次の通りです。
 
type ident with
    method-or-property1
    method-or-property2
 
identの部分に拡張の対象となるクラス名を書きます。(.NETのクラス等の、同一の名前空間、モジュール外にあるクラスの場合は完全修飾名で表記する必要があります。例 System.Int32)
 
それでは、int型に自前のメソッドを追加してみます。
 
> type System.Int32 with
    member this.MyDisplay () =
        printfn "%dだよ" this ;; //thisを使うところに注意してください。
 
 
type Int32 with
  member MyDisplay : unit -> unit
 
> (45).MyDisplay();;
45だよ
val it : unit = ()  
  

それでは宿題です。string型(System.String)に、その文字の長さを表示するメソッドMyPrintLengthを追加してみてください。
たとえば "world".MyPrintLenght ()で「文字数は5文字です」と表示するようにしてください。

スポンサーサイト

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

コメントの投稿

非公開コメント

前回の宿題

let order3u = { new IComparer<int*float*int> with
member this.Compare(l,r) =
let ((_,_,l3),(_,_,r3)) = l,r
l3 - r3
}
でもOKですか?

No title

もちろんです(というよりも、BLUEPIXYさんの方が正道ではないかと思います。)ブログ内で紹介させて頂きました。どうもありがとうございました。

正道

正道とか言われると、恥ずかしいですが・・
Sort メソッドには、IComparer のメソッドでなくて
単に比較関数を渡しても良いので、
t.Sort((fun a b -> let ((_, _, a), (_, _, b)) = a, b in a - b))
でいいですね。
(そうすると、IComparer のインスタンスを作ってソートという題意にはずれてしまうわけですが・)

No title

> (注意)F#のコードで定義された、extnsion methodはC#やVB.NETから使用することはできません。
ちょっと語弊がありますね。この辺、正式な用語がいまいちよくわからないので言及しにくいところであるのですが、ここで言われている Extension Method とは、MSDN で Type Extension と呼ばれているものですね。

http://msdn.microsoft.com/en-us/library/dd233211%28VS.100%29.aspx

C# および VB.NET いうところの Extension Method が欲しければ、ExtensionAttribute を使って以下のように定義してください。

[<System.Runtime.CompilerServices.ExtensionAttribute>]
module public Int32Extentions =
[<System.Runtime.CompilerServices.ExtensionAttribute>]
let MyDisplay (self:int32) = printfn "%dだよ" self

No title

いげ太さん。御指摘ありがとうございます。(それと先日は長くお付き合いいただきありがとうございました。)Extension methodsは今やType Extensionsというのですね。このF#の変化具合がF#本の新刊発行が遅れている理由なのだろうかと思う今日この頃です。

No title

削除することは、なかったんじゃないですかね?
(指摘自体、語弊があると言ってらっしゃるだけだし)
http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec2.aspx#_Toc207785740
でも、用語としては、type extension と説明されていますね。
その中で、
"The encoding of names is not specified in this release of F# and is not compatible with C# encodings of C# extension members"
「C#との拡張メンバーとコンパチではないよ」って言っているから、要するにそのことを説明したものですよね。
動作として、
F#で、
(45).MyDisplay()
とするものが、
C#で
(45).MyDisplay()
とするなら、用語はともかく、動作としては同じですしね。
逆に、いげ太さんのコードは、F#で作成したDLLをC#で、(45).MyDisplay() のように使えても、
F#の中でそのままで (45).MyDisplay() のようには使えませんし。
(つまり、F#でC#で使える拡張メンバーを作成できないのではないという指摘)

No title

どうしようか、悩んだんですが、入門編なので、混乱のもとになるといけないので、その部分そっくり削除させて頂きました。できれば、初級編あたりで、もう一度取り扱いたいと考えたいと思います。(せっかくのコメントが無駄になるようなことになってしまい申し訳ないです。)
プロフィール

T GYOUTEN

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

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

この人とブロともになる

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