【问题标题】:Unit-safe square roots单位安全平方根
【发布时间】:2010-12-03 01:00:31
【问题描述】:

我只是想知道如何编写用户定义的平方根函数 (sqrt),使其与 F# 的 unit system 正确交互。

应该是什么样子:

让 sqrt (x : float) = let x' = x / 1.0 // 删除单元 (x ** 0.5) * 1.0 // 重新分配单元

但这是不允许的,因为不允许非零常量具有通用单位

有没有办法写这个函数?使用内置的sqrt 可以正常工作,那么它有什么魔力呢?

【问题讨论】:

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


【解决方案1】:

允许非零泛型常量很容易破坏单元类型系统的安全性(请参阅 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>)

【讨论】:

    【解决方案2】:

    @kvb 是对的,更笼统地说:

    如果您有一个非单元感知算法(例如,假设您编写“立方根”),并且您想在其上放置单元,您可以将算法包装在具有正确类型签名的函数中并使用例如“浮动”以在单位进入时将其“丢弃”,以及在退出时“加回”适当单位的箱式向下投法。

    在 RTM 版本(Beta2 之后)中,F# 将具有用于“添加回单元”的原始库函数,因为 box-and-downcast 方法目前是一种破解方法,以克服在语言/库。

    【讨论】:

    • 谢谢 - 你能给这些新的库函数命名吗(链接)?
    • 它们可能会被命名为例如LanguagePrimitives 模块中的“val inline FloatWithMeasure : float -> float”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多