跨类型会话维护度量单位 [英] Maintaining Units of measure across type converstions

查看:84
本文介绍了跨类型会话维护度量单位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我们定义一个度量单位,例如:

[<Measure>] type s

,然后是带小数的整数

let t = 1<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/zh-cn/library/dd233243.aspx)所说的感觉不一样,是正确的解决方案

但是,在编写互操作性层时,还可以使用一些显式函数将无单位值转换为带单位的值.这些位于Microsoft.FSharp.Core.LanguagePrimitives模块中.例如,要从无单位浮点数转换为浮点数,请使用FloatWithMeasure,如以下代码所示.

似乎建议在F#代码中避免使用该函数.

是否有更惯用的方式来做到这一点?

解决方案

(注意:我在愤怒中使用的单位不多.)

我认为使用例如FloatWithMeasure是单位广播方面(从无到有).我认为这在概念上与数字表示法转换方面正交(例如intfloat).但是,(我认为)没有库函数可以对单位值进行数字表示法转换.也许这反映了一个事实,即大多数单位值都是对现实世界中的连续值进行建模的事实,因为通常不使用像int这样的离散表示形式(例如1<s>感觉不对;您肯定是指1.0<s>).

因此,我认为先投射表示形式"然后重新调整单位"是可以的,但是我不知道您是如何首先获得具有不同表示形式的值的,因为通常将这些表示形式固定在域中(例如,在任何地方都使用float.

(无论如何,我都很喜欢您的floatMeasure函数,该函数从表示形式方面取消了单元方面的混淆,因此,如果您只需要更改表示形式,则可以直接表达它)

If we define a unit of measure like:

[<Measure>] type s

and then an integer with a measure

let t = 1<s>

and then convert it to a float

let r = float t

we see that r = 1.0 without a measure type. This seems very odd, as all the measure information has been lost.

You can use LanguagePrimitives.FloatWithMeasure to convert back to a float with something like

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

which enforces the right types, but this doesn't feel like the right solution as the docs for units of measure (http://msdn.microsoft.com/en-us/library/dd233243.aspx) say

However, for writing interoperability layers, there are also some explicit functions that you can use to convert unitless values to values with units. These are in the Microsoft.FSharp.Core.LanguagePrimitives module. For example, to convert from a unitless float to a float, use FloatWithMeasure, as shown in the following code.

Which seems to suggest that the function should be avoided in F# code.

Is there a more idiomatic way to do this?

解决方案

(Caveat: I've not used units much in anger.)

I think that the only negative for using e.g. FloatWithMeasure is the unit-casting aspect (unitless to unitful). I think this is conceptually orthogonal to the numeric-representation-casting aspect (e.g. int to float). However there is (I think) no library function to do numeric-representation-casting on unit-ful values. Perhaps this is reflective of the fact that most unitful values model real-world continuous values, as so discrete representations like int are typically not used for them (e.g. 1<s> feels wrong; surely you mean 1.0<s>).

So I think it's fine to 'cast representations' and then 'readjust units', but I wonder how you got the values with different representations in the first place, as it's often typical for those representations to be fixed for a domain (e.g. use float everywhere).

(In any case, I do like your floatMeasure function, which un-confounds the unit-aspect from the representation-aspect, so that if you do need to only change representation, you have a way to express it directly.)

这篇关于跨类型会话维护度量单位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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