2014-03-25 39 views
2

让我们说一些奇怪的原因我想有这样的功能:F#运算符重载奇怪behavoir

let (~-) (str:string) = 42 

所以我可以做这样的事情,并得到42结果:

-"test" 
val it : int = 42 

哪很好。但现在,当我做:

let a = 100 
-a 

我得到:

error FS0001: This expression was expected to have type 
    string  
but here has type 
    int  

任何想法,为什么会出现这种情况?

回答

7

当您使用let定义运算符时,新定义隐藏了运算符的所有先前定义。因此,在您的示例中,您隐藏了一元减号(它适用于数字)的默认实现,并将其替换为仅适用于字符串的新运算符。

重新定义内置类型的重载操作符并不容易。如果你需要这样做,避免使用操作符可能更好(只使用函数)。但是,如果你想提供一个自定义类型重载运算符,你可以通过添加操作静态成员做到这一点:

type MinusString(s:string) = 
    member x.Value = s 
    /// Provide unary minus for MinusString values 
    static member (~-) (ms:MinusString) = 
    MinusString("-" + ms.Value) 

-(MinusString "hi") // Returns "-hi" 

如果你真的要重新定义内置的操作类似一元减号,使它在string上工作,那么实际上有一种方法可以使用trick described in earlier SO answers来实现。但是,如果您有充分的理由,我只会使用它。

1

简单地说,你重写了一个接受一个字符串并返回一个int的minus操作符,然后试图将它应用到一个int,而这已经不能再做了。