首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F# 'unbox浮动x‘vs. 'unbox int x’奇怪的编译结果

F# 'unbox浮动x‘vs. 'unbox int x’奇怪的编译结果
EN

Stack Overflow用户
提问于 2014-02-15 13:06:12
回答 1查看 143关注 0票数 1

这是在我查看以下问题时出现的:F# Unit of Measure, Casting without losing the measure type --请注意,我并不试图使用这个未打开的代码,我只是在回答这个问题时发现了一些奇怪的行为。

为什么下面的代码工作

代码语言:javascript
复制
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。

代码语言:javascript
复制
let float32ToFloat (x:float32<'u>) : float<'u> = unbox float x
float32ToFloat 1.0f<second>

如果我在(float x)周围放置parantheses,代码就会像预期的那样工作,所以我假设它必须是一些表达式计算/类型推断规则。这里到底发生了什么,为什么在第二种情况下需要副词?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-15 14:03:56

代码片段中的微妙之处是unbox float x --编译器将其视为(unbox float) x。因此,这两个函数实际上是这样处理的:

代码语言:javascript
复制
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> (但不能转换为第二种类型--因为您正在执行不安全的转换)。

因此,主要问题是实现中的括号错误(这会导致一个非常微妙的问题)。我想你可能想要这样的东西:

代码语言:javascript
复制
let intToFloat (x:int<'u>) : float<'u> = unbox (float x)
let float32ToFloat (x:float32<'u>) : float<'u> = unbox (float32 x)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21797974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档