为什么我在FSharp中得到一个无效的运算符定义:(〜!)

时间:2013-06-16 16:39:34

标签: f# operator-overloading

type Parameter =
    | Fixed of double
    | Free of double ref
    with
    override m.ToString() = 
        match m with
        | Fixed v -> sprintf "%f" v
        | Free  v -> sprintf "$%f" v.Value
    static member (~!) m =
        match m with
        | Fixed v -> v
        | Free v -> !v

我尝试定义~!的运算符会导致错误,但根据http://msdn.microsoft.com/en-us/library/dd233204%28VS.100%29.aspx !是一个有效的前缀运算符。

(~+)工作正常

具体错误是

    Error FS1208: Invalid operator definition. 
    Prefix operator definitions must use a valid prefix operator name. 
    (FS1208) (SketchSolveFS)

1 个答案:

答案 0 :(得分:1)

(!)always a valid prefix operator,因此您无需使用代字号(~)将其指定为前缀运算符。

不幸的是,当我对您的代码进行更改时,我只是收到一条新的错误消息。前一段时间(在F#2.0的某个时候,我认为)我尝试了类似的东西,发现F#编译器(包括2.0和3.0)包含一个错误,根据F#语言规范有效的某些前缀运算符显然是硬编码到编译器(可能在类型推理器或成员解析器中) - 如此有效,它们不能被重载。 IIRC,这会影响(至少)(!)(~&)(~&&)运营商。

这是您的代码,包含更改以及示例用法(编译器发出新错误的位置):

type Parameter =
    | Fixed of double
    | Free of double ref
with
    override m.ToString() = 
        match m with
        | Fixed v -> sprintf "%f" v
        | Free  v -> sprintf "$%f" !v
    static member (!) m =
        match m with
        | Fixed v -> v
        | Free v -> !v

let p = Free (ref System.Math.PI)
let value = !p    // Error is emitted for 'p'

错误的文字:

error FS0001: This expression was expected to have type    'a ref    but here has type    Parameter

最后,您可以通过重载(!!)运算符而不是(!)来解决此问题。