我只是想知道如何以一種與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
它工作正常,所以它執行什麼魔術?
我只是想知道如何以一種與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
它工作正常,所以它執行什麼魔術?
允許使用非零通用常量可以很容易地破壞單位類型系統的安全性(參見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>)
@kvb是正確的,更普遍:
如果你有一個非單元感知算法(例如說你寫'立方體根'),並且你想把單位放在它上面,你可以用一個正確的類型簽名將函數包裝在一個函數中,然後使用例如當他們進來的時候「漂浮」到「拋棄」單位,以及在出口的時候用方框和倒立的方法「加回」相應的單位。
在RTM版本(Beta2之後)中,F#將爲'加回單元'提供原始庫函數,因爲box-and-downcast方法目前是克服這些原語缺乏語言/圖書館。
相關問題:(也由@kvb回答)http://stackoverflow.com/questions/1398611/f-ununit-reunit-inside-a-function – Benjol