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

时间:2014-04-17 11:56:27

标签: static f# 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 

错误是

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

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

当我尝试写

override x.ToString() = Responses.Failure.toString x

我得到了

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

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

1 个答案:

答案 0 :(得分:8)

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

我认为这可能是一个错误 - 所以请报告on the F# CodePlex site

作为一种解决方法,我只提出了一个相当丑陋的想法,即定义一个私有类型别名,例如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