9

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

它应该是什么样子:

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

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

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

4

2 回答 2

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>)
于 2009-10-01T18:55:57.250 回答
6

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

如果你有一个非单元感知算法(例如,你写了'cube root'),并且你想在上面放置单元,你可以将算法包装在一个具有正确类型签名的函数中,并使用例如“float”来'当他们进来时抛弃”这些单位,并在退出时“添加”适当的单位。

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

于 2009-10-01T20:51:26.003 回答