1
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)
4

1 回答 1

1

(!)始终有效的前缀运算符,因此您无需使用波浪号 ( ~) 将其指定为前缀运算符。

不幸的是,当我对您的代码进行更改时,我只收到一条新的错误消息。不久前(我想是在 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

最后,您可以通过重载(!!)运算符而不是(!).

于 2013-06-16T17:06:40.507 回答