F# 在类型成员中使用内联失败,并出现FS1114、FS1113、FS1116、FS1118
我被这些错误击中了。从那时起,我简化了很多事情,并在很长一段时间内使用了工作代码,直到我需要重写F# 在类型成员中使用内联失败,并出现FS1114、FS1113、FS1116、FS1118,f#,inline,type-inference,F#,Inline,Type Inference,我被这些错误击中了。从那时起,我简化了很多事情,并在很长一段时间内使用了工作代码,直到我需要重写Equals。它使用了一个F#似乎并不满意的内联成员 基本上,该场景可以用以下代码进行总结: [<Flags>] type MyType = | Integer = 0b0001 | Float = 0b0010 module Test = [<CustomEquality;NoComparison>] type SomeType =
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
当我删除类型装饰other:SomeType
时,错误消失。我不知道这有什么关系,因为我认为,具有相同静态推断方法的较窄类型不应该引起此错误
由于override x.Equals
有一个类型注释obj
,我不知道如何利用这一知识(去掉类型修饰)来帮助我。似乎F编译器无法对无序代码进行内联。正如您在下面的评论中正确指出的,这似乎是一个bug
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 f
开放系统
[]
类型MyType=
|整数=0b0001
|浮动=0b0010
模块测试=
[]
打字=
|int64的整数
|浮子的浮子
静态成员内联op_Explicit(n:SomeType):float=
匹配
|Int i->float i
|浮动f->f
静态成员内联op_显式(n:SomeType):int64=
匹配
|Int i->i
|浮点f->int64 f
静态成员内联getType x=
将x与
|Int->MyType.Integer
|Float->MyType.Float
覆盖x。等于其他=
相配
| :? 某些类型为y->
//下面一行介绍如何编译此
将SomeType.gettypex&&SomeType.gettypey与匹配
|MyType.Integer->int64 x=int64 y//最高的类型是Integer(两者都是int)
|MyType.Float->Float x=Float y//最高的类型是Float(要么是Float,要么两者都是Float)
|>错误//不可能
|_u->false
重写x.GetHashCode()=
将x与Int i->hash i | Float f->hash f匹配
您可以通过不使用函数
而使用显式参数+匹配
来解决此问题<代码>函数产生一个值;值不能内联static member inline getType x=match x with Int |->MyType.Integer | Float |->MyType.Float
@ildjarn,感谢您的建议,但这不会改变错误,请尝试,在FSI中复制它。但是你是对的,有时候内联使用函数(静态成员),有时候不使用(让绑定),不知道为什么,但这是另一回事。不管怎样,错误仍然存在。@ildjarn,顺便说一句,我更新了Q(实现您的建议),这样就不会混淆错误的来源。在没有编译的情况下,F#编辑器、推理和intellisense不会抱怨。您认为这解决了问题是正确的,但代码顺序并不错误:在类内部以及带有和
的类之间,顺序是不相关的。我,我们似乎得出了大致相同的结论:)。这是正确的。谢谢你报告这个错误。我的最佳猜测是,即使在解析模块代码时,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 f