(hatena (diary ’Nobuhisa)) このページをアンテナに追加 RSSフィード Twitter

10/09/20 :

[]GeneralizableValueAttribute

特に意味はないのですが、頭痛を癒すためにVisual Studioを立ち上げました。ただのひとり遊びです。

type Person() = class end
type Dog()    = class end
type Cat()    = class end

type MyCollection<'T>() =
    static let arr = new ResizeArray<'T>() // static がミソだよ!
    member self.Add = arr.Add
    override self.ToString() = typeof<'T>.Name + "\t× " + arr.Count.ToString()

[<GeneralizableValue>]
let collection<'T> = new MyCollection<'T>()

[<EntryPoint>]
let Main args =
    collection.Add <| Person()
    collection.Add <| Dog()
    collection.Add <| Cat()
    collection.Add <| Dog()
    collection.Add <| Cat()
    collection.Add <| Cat()
    
    printfn "%A" (collection<Person>)
    printfn "%A" (collection<Dog>)
    printfn "%A" (collection<Cat>)
    
    0

Person  × 1
Dog     × 2
Cat     × 3
続行するには何かキーを押してください . . .

Main関数内だけ見るとなかなか不思議。

手当たり次第に詰め込んだのに、中の人がきちんと仕分けしてくれています。


ちなみに、GeneralizableValueAttribute を付けると関数に変換されるようです。

追記:コメント欄で いげ太さんにご指摘いただきましたが、この属性の有無は関係ないようです。

上の例だと以下のように展開されていました。

[GeneralizableValue]
public static MyCollection<T> collection<T>()
{
    return new MyCollection<T>();
}

いげ太いげ太 2010/09/21 11:11 >     printfn "%s" (collection)
>     printfn "%s" (collection)
>     printfn "%s" (collection)
"%A" のタイポですかね。

> GeneralizableValueAttribute を付けると関数に変換されるようです。
collection<'T> がメソッドとして IL に展開されるのは、GeneralizableValue 属性が付いているからではなくて、ジェネリックな値だからです。collection<'T> から GeneralizableValue 属性を外しても、同様のメソッドとして展開されるのが確認できます。

GeneralizableValue 属性に関しては、Dmitry Lomov 氏の記事が詳しいです。

Finer Points of F# Value Restriction
http://blogs.msdn.com/b/mulambda/archive/2010/05/01/value-restriction-in-f.aspx

NobuhisaNobuhisa 2010/09/21 22:32 ちょっと面白いかなと思って投稿してみたけど1日経ってよく見てみると全然普通で面白くもなんともなかったという噂のエントリにようこそ!(謎

ご指摘ありがとうございます。
%A の件は日記の編集上のあほミスです。。ごめんなさい。訂正いたしました。
ご紹介いただいたURL見てみます!勉強してまいります!

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/Nobuhisa/20100920/1284984028