F#重载泛型类型的运算符

Jon*_*ing 3 generics mono f# inline operator-overloading

我正在尝试定义一个包含操作符重载的泛型类型的模块,但是单声道编译器似乎忽略了实现文件中的类型.我的界面文件如下:

module Vector
[<Sealed>]
type Vector<'a> =
  static member ( +. ) : Vector<'a> * Vector<'a> -> Vector<'a>
val make : 'a * 'a -> Vector<'a>
val coord : Vector<'a> -> 'a * 'a
Run Code Online (Sandbox Code Playgroud)

我的实施是

module Vector
type Vector<'a> =
  | V of 'a * 'a
  static member ( +. ) (V(x1,y1), V(x2,y2)) = V(x1+x2, y1+y2)
let make (x, y) = V(x, y)
let coord (V(x, y)) = (x, y)
Run Code Online (Sandbox Code Playgroud)

当我编译时,我得到:

fsharpc -a VectorParam.fsi VectorParam.fs
F# Compiler for F# 3.1 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License

/.../VectorParam.fs(4,19): error FS0034: Module 'Vector' contains
    static member Vector.( +. ) : Vector<int> * Vector<int> -> Vector<int>    
but its signature specifies
    static member Vector.( +. ) : Vector<'a> * Vector<'a> -> Vector<'a>    
The types differ
Run Code Online (Sandbox Code Playgroud)

我不明白,因为我使用的是标记类型.并且,如果我删除所有"<'a>"并用float替换剩余的类型别名,那么一切正常.任何人都可以帮我理解正确的语法吗?

谢谢,乔恩

Joh*_*mer 7

我会从放弃fsi文件开始 - 这不是真的需要.如果你真的需要它,创建它的最简单方法是将文件粘贴到fsi并复制输出,或者你可以让编译器为你生成一个.

在对数字类型进行类型推断时,最好使用内联成员.原因是F#真的喜欢使用int - 并且只要它看到+没有进一步约束的编译器就会推断出来int.这是因为在.NET类型系统中,并不能表达F#使用的所有约束.使用inline绕过这个.

这是一个可以直接粘贴到fsi的简单示例:

type Vector<'a> =
  | V of 'a * 'a
  static member inline ( +. ) (V(x1,y1), V(x2,y2)) = V(x1+x2, y1+y2);;

V(1,1) +. V(1,1);;
V(1.,1.) +. V(1.,1.);;
Run Code Online (Sandbox Code Playgroud)