我想创建一个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")
答案 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'
因此x
和y
都是名为A
的类型,但不一样。相同的逻辑适用于Person
和Animal.Person
,并且取决于您定义它们的顺序,最后定义的将是键入Person
时引用的顺序。
如上所述,您可以使用新订单或定义订单来访问它们。您还可以决定将Person
类放在与Animal
不同的模块中。
module Inner =
type Person(name) ...
这样您就可以通过添加模块名称来访问您的类型。