让我们说出于一些奇怪的原因我想要这个功能:
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
知道为什么会这样吗?
答案 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,它不能再做了。