before in a much more complex scenario,我被这些错误击中了。从那时起,我已经简化了许多事情,并有了很长一段时间的工作代码,直到我需要重写Equals。它使用了一个内联的成员,而F#似乎对此并不满意。
基本上,这个场景可以用下面的代码来总结:
[<Flags>]
type MyType =
| Integer = 0b0001
| Float = 0b0010
module Test =
[<CustomEquality;NoComparison>]
type SomeType =
| Int of int64
| Float of float
override x.Equals other =
match other with
| :? SomeType as y ->
// following line throws on compiling this
match SomeType.getType x &&& SomeType.getType y with
| MyType.Integer -> int64 x = int64 y // highest type is integer (both are int)
| MyType.Float -> float x = float y // highest type is float (either is or both are float)
| _ -> false // impossible
| _ -> false
override x.GetHashCode() =
match x with Int i -> hash i | Float f -> hash f
static member inline op_Explicit(n: SomeType): float =
match n with
| Int i -> float i
| Float f -> f
static member inline op_Explicit(n: SomeType): int64 =
match n with
| Int i -> i
| Float f -> int64 f
static member inline getType x =
match x with
| Int _ -> MyType.Integer
| Float _ -> MyType.Float会引发以下错误(这与我之前的问题相似,但涉及复杂的鸭子类型)。
错误FS1114:值'Test.SomeType.getType‘被内联标记,但在优化环境中没有绑定 错误FS1113:值'getType‘是内联标记的,但它的实现使用的是内部函数或私有函数,该函数无法充分访问 警告FS1116:标记为“内联”的值具有意外的值 错误FS1118:未能将标记为“内联”的值“getType”内联,可能是因为递归值被标记为“内联”
现在,没有递归值,目标类型是已知的(由于匹配模式中的隐式强制转换为SomeType ),所以我不认为这种内联是不可能的。
有人对此有什么想法吗?或者是一个模式,包括内联的op_Explicit (如果删除getType,就会得到这些错误),最好也可以将getType作为内联的?
我知道我可以通过OO层次结构、接口和其他方法来解决这个问题,但是我更愿意使用这种方法,既为了清晰(类型系统是格型,不是层次结构),也是为了性能(带有内联的早期版本在测试场景中显示速度提高了4倍以上,而且速度很重要)。
作为事后考虑,以下更简单的场景也会引发这些错误:
module Test =
type SomeType =
| Int of int64
| Float of float
static member MyEquals (x, other: SomeType) =
// following line throws on compiling this
float x = float other
static member inline op_Explicit(n: SomeType): float =
match n with
| Int i -> float i
| Float f -> f
static member inline op_Explicit(n: SomeType): int64 =
match n with
| Int i -> i
| Float f -> int64 f当我移除类型装饰other: SomeType时,错误将消失。我不知道这有什么关系,因为我认为,使用相同静态推断方法的较窄类型不应该引起此错误。
而且,由于override x.Equals有obj的类型注释,我看不出如何利用这些知识(删除类型装饰)来帮助我。
发布于 2016-09-27 07:54:41
F#编译器似乎无法使用无序的代码进行内联。正如您在下面的评论中正确指出的那样,这似乎是一个错误。
open System
[<Flags>]
type MyType =
| Integer = 0b0001
| Float = 0b0010
module Test =
[<CustomEquality;NoComparison>]
type SomeType =
| Int of int64
| Float of float
static member inline op_Explicit(n: SomeType): float =
match n with
| Int i -> float i
| Float f -> f
static member inline op_Explicit(n: SomeType): int64 =
match n with
| Int i -> i
| Float f -> int64 f
static member inline getType x =
match x with
| Int _ -> MyType.Integer
| Float _ -> MyType.Float
override x.Equals other =
match other with
| :? SomeType as y ->
// following line throws on compiling this
match SomeType.getType x &&& SomeType.getType y with
| MyType.Integer -> int64 x = int64 y // highest type is integer (both are int)
| MyType.Float -> float x = float y // highest type is float (either is or both are float)
| _ -> false // impossible
| _ -> false
override x.GetHashCode() =
match x with Int i -> hash i | Float f -> hash fhttps://stackoverflow.com/questions/39707477
复制相似问题