这是在我查看以下问题时出现的:F# Unit of Measure, Casting without losing the measure type --请注意,我并不试图使用这个未打开的代码,我只是在回答这个问题时发现了一些奇怪的行为。
为什么下面的代码工作
let intToFloat (x:int<'u>) : float<'u> = unbox float x
intToFloat 1<second>虽然这会产生一个'Microsoft.FSharp.Core.FSharpFunc`2System.Single,:无法将类型为'float32ToFloat@86-6‘的对象强制转换为System.InvalidCastException System.Double。
let float32ToFloat (x:float32<'u>) : float<'u> = unbox float x
float32ToFloat 1.0f<second>如果我在(float x)周围放置parantheses,代码就会像预期的那样工作,所以我假设它必须是一些表达式计算/类型推断规则。这里到底发生了什么,为什么在第二种情况下需要副词?
发布于 2014-02-15 14:03:56
代码片段中的微妙之处是unbox float x --编译器将其视为(unbox float) x。因此,这两个函数实际上是这样处理的:
let intToFloat (x:int<'u>) : float<'u> =
let f = unbox float in f x
let float32ToFloat (x:float32<'u>) : float<'u> =
let f = unbox float in f x因此,您要接受float函数,将它(不安全地)转换为另一种类型的函数,然后调用它。第一种情况是int<'u> -> float<'u>,第二种情况是float32<'u> -> float<'u>。
我认为第一个方法有效,因为当编译器看到float函数(没有任何类型注释)时,它默认为int -> float,而且由于在运行时删除了度量单位,所以可以将其转换为int<'u> -> float<'u> (但不能转换为第二种类型--因为您正在执行不安全的转换)。
因此,主要问题是实现中的括号错误(这会导致一个非常微妙的问题)。我想你可能想要这样的东西:
let intToFloat (x:int<'u>) : float<'u> = unbox (float x)
let float32ToFloat (x:float32<'u>) : float<'u> = unbox (float32 x)https://stackoverflow.com/questions/21797974
复制相似问题