简体   繁体   English

在 F# 中一般将带有单位的浮点数转换为不同单位的问题

[英]Issue with generically casting a float with units to different units in F#

I am having a major issue handling units of measure in F#.我在处理 F# 中的测量单位时遇到了一个重大问题。 I have handled them successfully so far, but I have only either been removing units to get back a float or casting a float to one with units.到目前为止,我已经成功地处理了它们,但我只是要么移除单元以取回float ,要么将float转换为带有单元的浮点数。 However, now I have a use case where I need to generically drop units off of a float and give them new units.但是,现在我有一个用例,我通常需要从浮点数中删除单位并给他们新的单位。 At present, I see no way that this is possible in F#.目前,我认为这在 F# 中是不可能的。

For example:例如:

> let removeUnits (x: float<'Unit>) = float x;;
val removeUnits: x: float<'Unit> -> float

> let castUnits<[<Measure>] 'Unit> (x: float) = LanguagePrimitives.FloatWithMeasure<'Unit> x;;
val castUnits: x: float -> float<'Unit>

> let convertUnits<[<Measure>] 'NewUnit> (x: float<'OldUnit>) : float<'NewUnit> =
    x |> removeUnits |> castUnits<'NewUnit>;;

  let convertUnits<[<Measure>] 'NewUnit> (x: float<'OldUnit>) : float<'NewUnit> =
  -------------------------------------------------^^^^^^^^

stdin(8,47): warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The unit-of-measure variable 'OldUnit has been constrained to be measure '1'.

val convertUnits: x: float -> float<'NewUnit>

This almost seems like a bug to me.这对我来说几乎像是一个错误。 The types of the pipeline should be float<'OldUnit> -> float -> float<'NewUnit> , because those are the type signatures of the component functions.管道的类型应该是float<'OldUnit> -> float -> float<'NewUnit> ,因为这些是组件函数的类型签名。 I'm not understanding why out of nowhere that 'OldUnit is being constrainted to 1 .我不明白为什么'OldUnit被限制为1

How can I do this properly?我怎样才能正确地做到这一点? I want a function with signature val convertUnits: x: float<'OldUnit> -> float<'NewUnit> , where the function only changes the units and leaves the underlying float values alone.我想要一个带有签名val convertUnits: x: float<'OldUnit> -> float<'NewUnit> ,其中 function 仅更改单位并单独保留基础浮点值。

Is this a bug in the compiler?这是编译器中的错误吗?

That's just because you explicitly gave your function only one type parameter - 'NewUnit , - but in its signature you're using two - 'OldUnit and 'NewUnit .那只是因为你明确地给你的 function 一个类型参数 - 'NewUnit ,但在它的签名中你使用了两个 - 'OldUnit'NewUnit

Give the function both parameters like this:给 function 两个参数,如下所示:

let convertUnits<[<Measure>] 'NewUnit, [<Measure>] 'OldUnit> (x: float<'OldUnit>) : float<'NewUnit> =
    x |> removeUnits |> castUnits<'NewUnit>

Or, alternatively, let the compiler infer them by itself:或者,或者,让编译器自己推断它们:

let convertUnits (x: float<'OldUnit>) : float<'NewUnit> =
    x |> removeUnits |> castUnits<'NewUnit>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM