好的,有人可以向我解释为什么F#允许你超载>和^运算符,但不允许你使用它们?
+ (op_Addition): Works just fine.
^ (op_Concatenate): Compiler error in F#. Apparently only strings can be concatenated.
> (op_GreaterThan): Runtime Error – Failure during generic comparison: the type Program+OppTest4 does not implement the System.IComparable interface.
如果我将我的F#代码编译为库并使用VB中的那些运算符,它们都可以工作。如果我使用来自C#的那些运算符,除了op_Concatenate之外的所有运算符(如预期的那样)。但是F#不仅忽略了一些它们,静态类型检查器甚至不会告诉你它打算这样做。
编辑代码示例
type OppTest4(value: int) =
member this.value = value
static member (^) (left : OppTest4, right : OppTest4) =
OppTest4( Int32.Parse( left.value.ToString() ^ right.value.ToString() ))
static member (+) (left : OppTest4, right : OppTest4) =
OppTest4(left.value + right.value )
static member (>) (left : OppTest4, right : OppTest4) =
left.value > right.value
static member (<) (left : OppTest4, right : OppTest4) =
left.value < right.value
答案 0 :(得分:4)
F#具有对于F#合理的这些运算符符号的默认含义。您可以随时定义影响默认值的自己的含义,即la
let (>) x y = ...
例如,您可以将此运算符定义为“T.operator&gt;(U)”(假设x具有类型T且y具有类型U)。
请参阅源代码分发中FSharp.Core中的prim-types.fs以获取默认定义。 (它们非常重要!)
鉴于(1)缺乏对CLR上的类型类机制的支持(用于在一组其他无关类型中定义公共语义)和(2)原始类型(如'int)的事实的组合对于任何编程语言实现,通常需要特殊的(例如,System.Int32没有定义运算符+方法,但是大多数编程语言选择表现得好像存在这样的方法),很难想象任何通常可互操作的运算符东西今天在.Net上的所有语言。有很多设计权衡取决于语言选择要做什么(这里总结了太多的交互问题)。在任何情况下,您都应该能够从F#调用任何方法,如果不希望使用默认的操作符行为,则可以将操作符重新定义(阴影)为您想要的行为。如果您有特殊情况,请记住您在工作上遇到困难,请告诉我。
修改
我在
添加了更多细节答案 1 :(得分:0)
我同意,存在不一致性:可以定义运算符,但不能使用。
您是否在问,为什么F#设计师决定与System.IComparable接口进行比较而不是运算符重载?我不知道为什么,但在OO语言中我更喜欢IComparable而不是运算符重载。所以,我建议F#开发人员打破C#兼容性并禁止“静态成员(&gt;)(...)”语法糖。
如果您正在询问如何调用这些重载运算符,则非常简单:使用op_Concatenate,op_GreaterThan或op_LessThan静态成员。 (真的,我有一个编译器警告,描述了这个问题.F#1.9.6.16)
运行时错误转换为System.IComparable而没有任何编译器警告肯定是一个错误。您可以将其发送到fsbugs@microsoft.com。