2011-08-22 7 views
9

が、私はそれはそうF#単位で拡張メンバを定義するにはどうすればよいですか?

4.0<degree> |> degree.ToRadians 

のように比較的容易にそれらを使用することができ、我々は角度のような単位のない概念のための測定単位を使用する必要があるかどうか、私はF#で

type [<Measure>] degree = 
    static member ToRadians (d:float<degree>) : float<radian> = d * (Math.PI * 1.<radian>)/180.0<degree> 
and [<Measure>] radian = 
    static member ToDegrees (r:float<radian>) : float<degree> = r * 180.0<degree>/(Math.PI * 1.<radian>) 

degreeradian単位を定義したとしともかく同じような拡張部材もより手軽になるだろう。だから、そこです、これは私に次のエラー

error FS0010: Unexpected identifier in type name. Expected infix operator, quote symbol or other token. 

を取得します...私はちょうど

let d = 4.0<degree> 
let r = d.ToRadians() 

を言うことができる。しかし、私は延長部材に明白な方法

type float<degree> with 
    member degrees.ToRadians() = degree.ToRadians(degrees) 

を定義することはできませんF#での測定単位の拡張メンバの構文トリック、またはサポートされている機能ですか?

+0

私はそれがサポートされていないと推測する危険があります。私が試したすべてのものは、「測定値宣言は静的なメンバーしか持たない」というエラーを出しました。 – Daniel

+1

問題は、コンパイル後にメジャータイプの情報が削除されるため、実行時にはすべてが「float」なので、インスタンスメソッドを呼び出すことは意味がありません –

+1

@jpalmer。コンパイル時に、メンバーは静的に解決されます。 –

答えて

5

F#拡張メンバは、構築された汎用型の拡張を定義できないという点で、C#拡張メンバとは異なります。たとえば、seq<'t>に拡張子を定義できますが、seq<int>では定義できません。つまり、拡張メンバは実際には静的メソッドではなく、型のメンバのように動作します。これはあまりにも種類を測定するために適用されますので、あなたがfloat<degree>の拡張子を定義することはできませんが、あなたはfloat<[<Measure>]'u>に拡張を定義することができます。

type float<[<Measure>]'u> with 
    member f.Squared() = f * f 

[<Measure>] 
type m 

let area = 2.0<m>.Squared() 

しかし、私はこれはあなたのケースであなたをどのように役立つかを見ていません...

+0

これは意味があります。シンタックス以外の拡張メソッドを定義すると、実際のメリットはありません。他にもたくさんのオプションがあります。 –

関連する問題