2017-10-04 39 views
1

我想要創建一個Person實例。人是一種動物。當我嘗試創建一個Person時,IDE對我說:「這個表達式預計會有'Person'類型,但是這裏有'Animal'類型。使用同名聯盟類型創建新對象

type Person(name) = 
    member this.Name: string = name 

type Animal = 
| Person of Person 
| Cat 
| Dog 

let person: Person = Person(name = "John") 
+0

我不知道爲什麼它是這樣的,所以我不會將它作爲答案添加它,但是如果您添加'new',它將起作用:'let person:Person = new Person(name =「John」)''。 – MarcinJuraszek

+0

@MarcinJuraszek我不想使用'new'關鍵字,如果我使用'new',IDE說我'新'是多餘的。 –

+0

有趣。我只在F#Interactive中測試過它。 – MarcinJuraszek

回答

1

問題是Person引用了歧視聯盟的類型和大小寫。

可以反轉的定義,因此將解決最後一個:

type Animal = 
    | Person of Person 
    | Cat 
    | Dog 
and 
    Person (name) = 
     member this.Name: string = name 

let person: Person = Person(name = "John") 

// then to create an animal 
let animal = Animal.Person (Person(name = "John")) 

替代解決方案是使用new關鍵詞作爲@MarcinJuraszek建議的意見或考慮杜情況和不同的名稱類型。

+0

「類型,例外或模塊'Person'的重複定義」。 –

+0

在這種情況下,你會如何創建一個'Animal'類型的人? – Matiasd

+0

@Matiasd我只發佈IDE所說的錯誤。聯合人員沒有參數,但Person類是。 –

1

在F#中,名稱可以作爲類型和值的綁定,並且您可以隨時重新定義名稱「指向」的名稱。例如。

// lets define type A 
type A(name) = member this.Name : string = name 
let x = A("test") 

// lets "bind" the type name 'A' to a new type 
type A(number) = member this.Number : int = number 
let y = A(10) 

printfn "type name of x: %s" (x.GetType().Name) // prints 'type name of x: A' 
printfn "type name of y: %s" (y.GetType().Name) // prints 'type name of y: A' 

所以xy都是一個名爲A型的,但不一樣的。同樣的邏輯適用於PersonAnimal.Person,並且取決於您定義它們的順序,最後定義的將是在鍵入Person時引用的那個。

如上所述,您可以使用新的或定義順序來訪問兩者。您也可以決定將Person類放在與Animal不同的模塊中。

module Inner = 
    type Person(name) ... 

這樣,您可以通過預先輸入模塊名稱來訪問您的類型。