为什么'!='的使用被认为是含糊不清的,但是'='的类似用法不是?

Mik*_*ray 5 generics f#

我正在使用这个在线编译器玩一些F#代码(我找不到确切的F#编译器版本,这将在以后相关).我意识到以下两个功能非常不同:

let f x y = x = y
let g x y = x != y
Run Code Online (Sandbox Code Playgroud)

f是完全通用的,但令我惊讶的g是没有.调用g 1 2将导致消息的编译错误:

泛型构造要求类型'int'具有引用语义,但它不具有,即它是结构

我去了我自己的机器上尝试过这个(在单声道上使用F#3.0,但我在Visual Studio 2012中得到了相同的结果)并在我尝试定义时收到了完全不同的错误g:

错误FS0332:无法解决在此程序点或附近使用运算符'(!=)'所固有的模糊性.考虑使用类型注释来解决歧义.

为什么这种使用!=含糊不清,为什么会出错呢?另外,为什么这种使用被!=认为是模棱两可的但是使用=in f不是?新错误有助于提醒我一个自动泛化无法按预期工作的情况.但是,这似乎是两个不同版本的F#编译器之间的重大变化.搜索这两个错误消息都显示为空.我没有在F#规范中看到任何看似相关的内容.任何指向相关部分的指针都会有所帮助.

Duc*_*tro 13

注意,这!=不是F#中不等式运算符的名称,<>是.

http://msdn.microsoft.com/en-us/library/dd233228.aspx

使用<>应该与=您的示例中的相同.


Tom*_*cek 9

现有的答案解释了为什么代码没有按预期运行,所以让我只添加一个解释错误消息试图说明的内容.

F#支持自定义运算符,您将尝试在函数中使用的任何其他(有效)运算符符号获得相同的错误消息,例如fish运算符:

let fish x y = x <*>><< y
Run Code Online (Sandbox Code Playgroud)

在这种情况下,F#无法定义泛型函数,因为.NET没有指定泛型约束的方法,说明一个或另一个参数的类型支持<*>><<运算符(在.NET语言中,约束必须说一个类型需要特定的静态方法).

这不是比较或相等的情况(因为F#有一种表示这些的方法).但是,如果你使用像那样的东西,+你仍然不会得到泛型函数,而是一个专门的函数int.在这种情况下,您可以使用inline和编写通用的函数(需要+运算符):

let inline add x y = x + y
add 1 2
add 1.1 2.2
Run Code Online (Sandbox Code Playgroud)

同样,您可以定义一个需要任何自定义运算符(如fish或!=)的内联函数,但您仍然无法使用任何标准类型调用它.

  • +1很棒的细节,谢谢.这同样适用于[`¸.·'¯·.¯·¸¸¸····.¸> <((º>`运算符)(http://1lineart.kulaone.com/art/41)?:P (2认同)
  • @RubenBartelink您可以做的最好的事情可能是`.- ^ -..- ^ -..- ^ -..- ^ - .. >> <<*>`:-) (2认同)