单位安全的平方根

时间:2009-10-01 15:27:30

标签: math f# functional-programming units-of-measurement

我只是想知道如何以与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它可以正常工作,那么它有什么神奇之处呢?

2 个答案:

答案 0 :(得分: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>)

答案 1 :(得分:6)

@kvb是对的,更一般地说:

如果你有一个非单位识别算法(比如说你写'立方根'),并且你想在其上放置单位,你可以将算法包装在一个具有正确类型签名的函数中,并使用例如当他们进来时,“浮动”以“抛弃”这些单位,并且在出路时“盒装”和“向下”方法“加回”适当的单位。

在RTM版本中(在Beta2之后),F#将具有用于“添加单元”的原始库函数,因为盒式和垂直式方法目前是克服缺少这些基元的一个黑客攻击。语言/库。