使用联合类型的相同名称创建新对象

时间:2017-10-04 18:33:53

标签: f#

我想创建一个Person实例。人是一种动物。当我尝试创建一个Person时,IDE会说我&#34;这个表达式应该有类型&#39; Person&#39;,但这里有类型&#39; Animal&#39;&#34;。< / p>

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

type Animal =
| Person of Person
| Cat
| Dog

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

2 个答案:

答案 0 :(得分: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在评论中建议或考虑DU案例和类型的不同名称。

答案 1 :(得分:1)

在F#中,名称充当对类型和值的绑定,并且您可以随时重新定义名称&#34;指向&#34;至。 E.g。

// 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) ...

这样您就可以通过添加模块名称来访问您的类型。