F#运算符重载奇怪的行为

时间:2014-03-25 17:29:36

标签: f#

让我们说出于一些奇怪的原因我想要这个功能:

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    

知道为什么会这样吗?

2 个答案:

答案 0 :(得分: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 :(得分:1)

简单地说,你用一个带有字符串并返回一个int的减号运算符覆盖了减号运算符,然后尝试将它应用于一个int,它不能再做了。