2014-10-08 117 views
3

如何在F#中創建泛型類,約束條件是類型是度量?具有度量約束的泛型類

我已經試過,但A2和B2不產生錯誤:

open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames 

type Vector2D_A<[<Measure>] 'u>(x : float<'u>, y : float<'u>) = 
    member this.X = x 
    member this.Y = y 

type Vector2D_B<'t, [<Measure>] 'u>(x : 't, y : 't) = 
    member this.X = x 
    member this.Y = y 

type Vector2D_C<'t>(x : 't, y : 't) = 
    member this.X = x 
    member this.Y = y 

let a1 = Vector2D_A(1.0<metre>, 2.0<metre>) 
let b1 = Vector2D_A(1.0<metre>, 2.0<metre>) 
let c1 = Vector2D_C(1.0<metre>, 2.0<metre>) 

let a2 = Vector2D_A(1.0, 2.0) // should produce an error 
let b2 = Vector2D_A(1.0, 2.0) // should produce an error 
let c2 = Vector2D_C(1.0, 2.0) 

我想定義就像任何的這三個例子類(但不進行編譯):

1)

type Vector2D_B<'t, [<Measure>] 'u>(x : 't<'u>, y : 't<'u>) = 
    member this.X = x 
    member this.Y = y 

2)

type Vector2D_B<'t when 't :> 't<[<Measure>]>>(x : 't<'u>, y : 't<'u>) = 
    member this.X = x 
    member this.Y = y 

3)

type Vector2D_B<'t when 't :> 't<_>(x : 't<'u>, y : 't<'u>) = 
    member this.X = x 
    member this.Y = y 

回答

3

書寫「t是相當於寫入」 T < 1> - ,其中< 1>表示的計量單位爲無量綱值,其隱式應用被明確地提供測量的任何其他單元時。

因此,當您沒有明確提供度量單位時,您不能強制編譯器生成錯誤消息,因爲當您這樣做時,隱式提供無量綱值的度量單位。

3

擴展BillH的例子。

考慮乘法方法的簡單情況:的

float<'a> -> float<'b> -> float<'a'b> 

let mult a b = a * b 

這有一個簽名(比如浮動)現在,如果'a = 1/'b簽名

float<'a> -> float<1/'a> -> float<1> 

現在拋出編譯器錯誤是不合理的。例如,特定的調用只能通過一些特定的輸入到一些更高階的函數來進行。因此,沒有簡單的方法來指定某些通用的計量單位的某些約束條件(儘管有些可能在例如平方根函數中)。

即使對給定函數的單位執行運行時測試也很難,因爲在編譯代碼後,度量單位信息會被丟棄。