2009-10-01 43 views
9

我只是想知道如何以一種與F#的unit system正確交互的方式編寫用戶定義的平方根函數(sqrt)。單位安全的平方根

它應該是什麼樣子:

 
let sqrt (x : float<'u^2>) = 
    let x' = x/1.0<'u^2> // Delete unit 
    (x ** 0.5) * 1.0<'u>  // Reassign unit 

但這是不允許不被允許由於非零常數有通用單位

有沒有辦法寫這個函數?內置sqrt它工作正常,所以它執行什麼魔術?

+1

相關問題:(也由@kvb回答)http://stackoverflow.com/questions/1398611/f-ununit-reunit-inside-a-function – Benjol

回答

6

允許使用非零通用常量可以很容易地破壞單位類型系統的安全性(參見Andrew Kennedy的papers)。我相信最後一個問題的答案是sqrt在某種意義上的確是神奇的,因爲通過常規方法不可能用該類型簽名來定義參數函數。然而,可以做你想做的(至少在F#的當前版本)採取拳擊和鑄造的優勢:

let sqrt (x : float<'u^2>) = 
    let x' = (float x) ** 0.5 (* delete unit and calculate sqrt *) 
    ((box x') :?> float<'u>) 
6

@kvb是正確的,更普遍:

如果你有一個非單元感知算法(例如說你寫'立方體根'),並且你想把單位放在它上面,你可以用一個正確的類型簽名將函數包裝在一個函數中,然後使用例如當他們進來的時候「漂浮」到「拋棄」單位,以及在出口的時候用方框和倒立的方法「加回」相應的單位。

在RTM版本(Beta2之後)中,F#將爲'加回單元'提供原始庫函數,因爲box-and-downcast方法目前是克服這些原語缺乏語言/圖書館。

+0

謝謝 - 你能命名這些新的庫函數(鏈接)? – Dario

+3

他們可能會被命名爲例如在語言原語模塊中的「val inline FloatWithMeasure:float - > float <'u>」。 – Brian

+0

這是它:http://msdn.microsoft.com/en-us/library/ee806527(VS.100).aspx – Benjol