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