单位安全的平方根

Dar*_*rio 9 math f# functional-programming units-of-measurement

我只是想知道如何以与F#单位系统正确交互的方式编写用户定义的平方根函数(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它工作正常,它有什么神奇的表现?

kvb*_*kvb 6

允许非零通用常量可以很容易地打破单位类型系统的安全性(参见Andrew Kennedy的论文).我相信你的上一个问题的答案sqrt在某种意义上确实是神奇的,因为不应该通过常规手段定义具有该类型签名的参数函数.然而,这可以做到你想要什么(至少在F#的当前版本),通过利用拳击和铸造:

let sqrt (x : float<'u^2>) =
  let x' = (float x) ** 0.5 (* delete unit and calculate sqrt *)
  ((box x') :?> float<'u>)
Run Code Online (Sandbox Code Playgroud)


Bri*_*ian 6

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

如果你有一个非单元识别算法(比如说你写'cube root'),并且想要在其上放置单位,你可以将算法包装在一个具有正确类型签名的函数中,并使用例如"float"to'抛弃'他们进来的单位和盒子和垂头丧气的方法'在出路时'加回'适当的单位.

在RTM版本中(在Beta2之后),F#将具有用于"添加单元"的原始库函数,因为盒式和垂直式方法目前有点克服了语言/库中缺少这些原语的问题. .

  • 它们可能会在LanguagePrimitives模块中命名为例如"val inline FloatWithMeasure:float - > float <'u>". (3认同)