2017-07-28 100 views
4

我是F#的新手,我正在嘗試一些事情來讓我的頭腦對這個語言感興趣。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;} 

而且這裏的時候,我想協調的返回類型,我找不到如何指定收益用於這項功能:

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 

我在默認情況下出現此錯誤:此表達式預計有'Vector',但此處有'Coordinate'類型

我累了有這個網站的功能特徵上一看,但不能爲東西我的問題:https://fsharpforfunandprofit.com/posts/function-signatures/

問題:

你如何解決這個錯誤?

是因爲推理類型默認情況下采取聲明的最後一個類型匹配的屬性(在我的例子向量)是什麼?

獎勵:有沒有更好的方式來處理這種情況在F#?

在此先感謝

回答

6

由於使用的是他們的成員名稱構成記錄:

{ X = 2; Y = 3} 

創建矢量和座標之間的命名衝突。在F#中,編譯器總是會在這種情況下解決最新的定義,因此,在您的示例中,編譯器將把記錄{X = ...,Y = ...}解釋爲Vector。

有上F# records on fsharpforfunandprofit.com好文章,解釋如何處理這一點很容易,我建議你閱讀的一個很好的解釋。

但總之,你可以前綴記錄類型的記錄實例的任一成員:

{ Coordinate.X = 2; Y = 3 } // Creates a Coordinate 
{ X = 2; Coordinate.Y = 3 } // Creates a Coordinate 

{ Vector.X = 2; Y = 3 } // creates a vector 
+0

謝謝正是我一直在尋找,並聯繫好纔是真的好。 –