Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#和运算符重载:(>;)和(^)_F#_Operator Overloading_Static Typing - Fatal编程技术网

F#和运算符重载:(>;)和(^)

F#和运算符重载:(>;)和(^),f#,operator-overloading,static-typing,F#,Operator Overloading,Static Typing,好的,有人能给我解释一下为什么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 Progra

好的,有人能给我解释一下为什么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#u之外的所有操作符都会连接工作(如预期的那样)。但是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
输入OppTest4(值:int)=
成员this.value=value
静态成员(^)(左:OppTest4,右:OppTest4)=
OppTest4(Int32.Parse(left.value.ToString()^right.value.ToString())
静态成员(+)(左:OppTest4,右:OppTest4)=
OppTest4(left.value+right.value)
静态成员(>)(左:OppTest4,右:OppTest4)=
left.value>right.value
静态成员(F#)对这些运算符符号具有默认含义,这对于F#来说是合理的。您可以始终定义自己的含义,以隐藏默认值

let (>) x y = ...
例如,您可以将此运算符定义为“T.operator>(U)”(假设x的类型为T,y的类型为U)

有关默认定义,请参见源代码发行版中FSharp.Core中的prim-types.fs。(它们非常重要!)

考虑到(1)在CLR上缺乏对类类型机制的支持(用于在一组其他不相关的类型之间定义公共语义)和(2)基元类型(如“int”)通常需要为任何编程语言实现指定特殊情况的事实(例如System.Int32没有定义运算符+方法,但大多数编程语言都选择这样一种方法),很难想象现在.Net上的所有语言都有通用的可互操作运算符。根据语言的具体选择,有很多设计权衡(这里总结的交互问题太多了)。在任何情况下,您都应该能够从F#调用任何方法,并且如果默认运算符行为不受欢迎,您可以将运算符重新定义(阴影化)为所需的行为。如果您认为某个特定的场景在工作中遇到困难,请告诉我

编辑

我在网站上添加了更多细节


我同意,存在不一致性:运算符可以定义,但不能使用

你是在问,为什么F#设计人员决定实现与System.IComparable接口的比较而不是运算符重载?我不知道为什么,但在OO语言中,我更喜欢IComparable而不是运算符重载。因此,我建议F#开发人员打破C兼容性并禁止“静态成员(>)(…)”语法糖

如果您想知道如何调用这些重载运算符,那么很容易:使用op#u Concatenate、op#u GreaterThan或op#LessThan静态成员。(实际上,我得到了一个编译器警告,描述了这个问题。F#1.9.6.16)


在没有任何编译器警告的情况下将运行时错误转换为System.IComparable肯定是一个错误。您可以将其发送到fsbugs@microsoft.com.

好的,那么为什么这个不起作用呢?“静态成员(>)(左:OppTest4,右:OppTest4)=left.value>right.value”>现在很难想象在.Net上有任何跨所有语言的通用运算符。<但是有!如果你使用我在问题中展示的代码,VB将尊重所有运算符。F#发出标准IL代码,它只是不使用它。我想知道我是否可以只为一种类型的我们隐藏默认运算符定义正在使用let绑定-我无法控制类型实现。如果是这样,该如何实现?我尝试了let(>)(a:SomeType)(b:SomeType)=…但是其他类型之间的任何比较都失败了,因此2>1不再编译。@emaster,不,你不能只对一种类型进行阴影处理。总之,如果我能在下周留出几个小时,我会尝试写博客,因为有很多不同的交互力量在起作用。与此同时,其他人发布了一个很好的日志运行时错误不是bug,是设计造成的。但是,我还没有看到关于这个设计的公开讨论,尽管不明显,但它的动机很好,所以我会尽快纠正。好的,不可能证明,OppTest4的每个实例都没有IComparable接口。但仍然知道有OppTest4插件无法转换为IComparable的tances!因此必须至少有一个警告!为什么不呢?@.vpolozov.name:看起来F#spec()的第9.6节表明,他们正在考虑在某些情况下添加警告,在这些情况下,比较运算符的使用可能会失败。@kvb似乎链接已失效=(