区分联合方法不会看到其静态成员

Rus*_*tam 4 f# static discriminated-union

问题似乎很愚蠢,但我真的不明白.

module Responses =
    type Failure = 
        | Problem of string 
        | Error of exn 
        | Timeout
        static member toString x = 
            match x with
            | Problem str -> sprintf "Problem %s" str
            | Error e -> sprintf "Error %s" (e.ToString())
            | Timeout -> "Timeout"
        override x.ToString() = Failure.toString x 
Run Code Online (Sandbox Code Playgroud)

错误是

      override x.ToString() = Failure.toString x;;
--------------------------------------^^^^^^^^
stdin(11,41): error FS0039: The field, constructor or member 'toString' is not defined
Run Code Online (Sandbox Code Playgroud)

原因是f#因某种原因认为Failure属于类型Microsoft.FSharp.Core.Operations.Failure

当我试着写

override x.ToString() = Responses.Failure.toString x
Run Code Online (Sandbox Code Playgroud)

我明白了

Startup.fs(14,33): error FS0039: The namespace or module 'Responses' is not defined
Run Code Online (Sandbox Code Playgroud)

Failure例如xFailure,当我重命名时,它可以工作.但我真的不想重命名它.我可以以某种方式避免重命名和使用静态方法吗?

Tom*_*cek 8

这有点令人惊讶!我认为它正在发生,因为Failure是F#核心库中定义的另一种类型.当您尝试调用静态方法时,编译器(出于某种原因)仅选择F#库类型,但不会合并静态方法(这是我所期望的).

我认为这可能是一个错误 - 所以请在F#CodePlex网站上报告.

作为一种解决方法,我只提出了一个相当丑陋的想法,即定义一个私有类型别名FailureStatic,然后使用别名来调用静态成员(库的用户将看不到它).

module Responses =
    type private FailureStatic = Failure
    and Failure = 
        | Problem of string 
        | Error of exn 
        | Timeout
        static member toString x = 
            match x with
            | Problem str -> sprintf "Problem %s" str
            | Error e -> sprintf "Error %s" (e.ToString())
            | Timeout -> "Timeout"
        override x.ToString() = FailureStatic.toString x 
Run Code Online (Sandbox Code Playgroud)