F#类型和功能签名

Ced*_*and 4 f# type-inference

我是F#的新手,我正在尝试一些事情来解决这个问题.

我必须两种类型几乎相同(坐标和矢量).由于这种类型的推断无法正常工作,我很难在每个函数上指定正确的类型.

它在某种程度上不符合这里的矢量:

type Coordinate = {X:int; Y:int}
type Vector = {X:int; Y:int}

let calculateVector (origin:Coordinate) (destination:Coordinate) = { X=destination.X-origin.X; Y= destination.Y-origin.Y;}
Run Code Online (Sandbox Code Playgroud)

在这里,当我想要一个返回类型的Coordinate时,我找不到如何为此函数指定返回它:

let calculateNextCoordinate (coordinate:Coordinate) direction = 
   match direction with
   | "N" -> { X=coordinate.X; Y=coordinate.Y-1 }
   | "NE" -> { X=coordinate.X+1; Y=coordinate.Y-1 }
   | "E" -> { X=coordinate.X+1; Y=coordinate.Y }
   | "SE" -> { X=coordinate.X+1; Y=coordinate.Y+1 }
   | "S" -> { X=coordinate.X; Y=coordinate.Y+1 }
   | "SW" -> { X=coordinate.X-1; Y=coordinate.Y+1 }
   | "W" -> { X=coordinate.X-1; Y=coordinate.Y }
   | "NW" -> { X=coordinate.X-1; Y=coordinate.Y-1 }
   | _ -> coordinate
Run Code Online (Sandbox Code Playgroud)

我在默认情况下有这个错误:这个表达式应该有'Vector',但这里有'Coordinate'类型

我厌倦了在这个网站上查看功能签名,但对我的问题无法解决问题:https://fsharpforfunandprofit.com/posts/function-signatures/

问题:

你如何解决这个错误?

是因为推理类型默认采用与属性匹配的最后一种类型(在我的示例中为Vector)?

额外奖励:有没有更好的方法来处理F#中的这种情况?

提前致谢

Mat*_*asd 6

由于记录是使用其成员名称构建的:

{ X = 2; Y = 3}
Run Code Online (Sandbox Code Playgroud)

您在Vector和Coordinate之间创建了命名冲突.在F#中,编译器总是在这种情况下解析为最新定义,因此,在您的示例中,编译器会将记录{X = ...,Y = ...}解释为Vector.

关于fsharpforfunandprofit.com上的F#记录有一篇很好的文章,它解释了如何轻松处理这个问题,我建议你阅读以获得一个很好的解释.

但简而言之,您可以使用记录类型为记录实例的任一成员添加前缀:

{ Coordinate.X = 2; Y = 3 }  // Creates a Coordinate
{ X = 2; Coordinate.Y = 3 }  // Creates a Coordinate
Run Code Online (Sandbox Code Playgroud)

{ Vector.X = 2; Y = 3 } // creates a vector
Run Code Online (Sandbox Code Playgroud)