单位安全的平方根 [英] Unit-safe square roots

查看:141
本文介绍了单位安全的平方根的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道如何编写一个用户定义的平方根函数(sqrt),以便与F#的 unit system

它应该是什么样的:

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

但由于非零常数不允许有通用单位,所以这是不允许的。

是有办法写这个函数吗?使用内置的 sqrt 它可以正常工作,那么它执行什么魔术?

解决方案

允许非零通用常量可以很容易地破坏单位类型系统的安全性(请参阅Andrew Kennedy的论文)。我相信最后一个问题的答案是 sqrt 在某种意义上确实很神奇,因为通过正常方式定义一个具有该类型签名的参数函数是不可能的手段。但是,通过利用装箱和投射, 可以做到你想做的事情(至少在当前版本的F#中):

 let sqrt(x:float<'u ^ 2>)= 
let x'=(float x)** 0.5(*删除单位并计算sqrt *)
((box x'):?> float< u>)


I just wondered how it is possible to write a user-defined square root function (sqrt) in a way that it interacts properly with F#'s unit system.

What it should be like:

let sqrt (x : float<'u ^ 2>) =
    let x' = x / 1.0<'u ^ 2> // Delete unit
    (x ** 0.5) * 1.0<'u>     // Reassign unit

But this is disallowed due to nonzero constants not being allowed to have generic units.

Is there a way to write this function? With the builtin sqrt it works fine, so what magic does it perform?

解决方案

Allowing nonzero generic constants would make it very easy to break the safety of the type system for units (see Andrew Kennedy's papers). I believe that the answer to your last question is that sqrt is indeed magic in some sense in that it shouldn't be possible to define a parametric function with that type signature through normal means. However, it is possible to do what you want (at least in the current version of F#) by taking advantage of boxing and casting:

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

这篇关于单位安全的平方根的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆