2012-02-23 86 views
2

如果我们定义度量的像单元:维护单位

[<Measure>] type s 

,然后一个整数与量度

,然后将其转换为一个浮

let r = float t 

我们看到r = 1.0没有度量类型。这似乎很奇怪,因为所有的度量信息都已经丢失。

您可以使用LanguagePrimitives.FloatWithMeasure转换回一个浮动的东西,如

let inline floatMeasure (arg:int<'t>) : (float<'t>) = 
    LanguagePrimitives.FloatWithMeasure (float arg) 

其强制执行的权利类型,但是这并不觉得自己是正确的解决方案为文档的测量单位(HTTP: //msdn.microsoft.com/en-us/library/dd233243.aspx)说

然而,对于写作的互操作性层,也有,你可以用它来无量纲值转换为数值与单位一些明确的功能。这些位于Microsoft.FSharp.Core.LanguagePrimitives模块中。例如,要将无单位浮点数转换为浮点数,请使用FloatWithMeasure,如下面的代码所示。

这似乎表明该函数应该在F#代码中避免。

有没有更习惯的方式来做到这一点?

回答

1

(警告:我还没有使用的单位太多愤怒)

我认为,唯一的负面使用例如FloatWithMeasure是单位铸造方面(无单位)。我认为这在概念上与数字表现演绎方面正交(例如intfloat)。但是(我认为)没有库函数可以对单位值进行数值表示转换。也许这反映了这样一个事实:大多数单位值模拟真实世界的连续值,因为如int这样的离散表示通常不用于它们(例如1<s>感觉错误;当然你的意思是1.0<s>)。

所以我觉得'表示'然后'重新调整单位'很好,但是我想知道你是如何得到具有不同表示的值的,因为对于那些表达式来说这通常是固定的(例如,在任何地方都使用float)。 (在任何情况下,我都喜欢你的floatMeasure函数,它不会将表达方面的单位方面混淆,所以如果你只需要改变表示方式,就可以直接表达它。)

+0

我明白你的意思了。我想我会补充一点,这是因为我正在以离散时间步长进行仿真(对于这个步骤“int”很好),但是在我的一些方程中使用了总时间。可能真正的答案是完全避免使用int。 – 2012-02-23 09:17:01

1

这里的工作片段已经做了你所需要的东西,虽然在警告

标准输入(9,48):警告FS0042:此构造被弃用:它只是在F#库使用)):

[<NoDynamicInvocation>] 
let inline convert (t: int<'u>) : float<'u> = (# "" t : 'U #) 

[<Measure>] type s 
let t = 1<s> 
let t1 = convert t // t1: float<s> 

不过,我不会建议这种方法。
首先,UoM是编译时,而类型转换let r = float t是运行时。在调用时,int -> float不知道它是否为int<s>int<something_else>。所以在运行时根本无法推断出正确的float<'u>

另一个想法是,UoM背后的哲学比它所描述的更广泛。这就像是说编译器,“好吧,它是int,但请把它当作int<s>”。目标是避免偶尔不当使用(例如,将int<s>添加到int<hours>)。
有时它没有意义int -> float转换:想想int<ticks>,没有意义float<ticks>

Further reading,归功于@kvb指向本文。

+0

'let t1:float = unbox float t'也适用,但它不是通用的。 – bytebuster 2012-02-24 17:35:39