John Doe
John Doe

Reputation: 493

Create new object with the same name of the union type

I want create an instance of Person. Person is a type of Animal. When I try to create a Person, the IDE says me "This expression was expected to have type 'Person', but here has type 'Animal'".

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

type Animal =
| Person of Person
| Cat
| Dog

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

Upvotes: 1

Views: 87

Answers (2)

Matiasd
Matiasd

Reputation: 571

In F# names acts as bindings to types and values and at any time you can redefine what a name "points" to. 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'

So x and y are both of a type named A, but not the same. The same logic applies to Person and Animal.Person, and dependent on the order you define them in, the last defined will be the one referenced when typing Person.

As mentioned, you can use new or definition order to access both. You could also decide to put the Person class in a different module than Animal.

module Inner = 
    type Person(name) ...

This way you can access your types by prepending the module name.

Upvotes: 1

Gus
Gus

Reputation: 26184

The problem is that Person refers to both the type and the case of the Discriminated union.

You can invert the definitions so it will resolve to the last one:

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"))

Alternatives solutions are to use new keyword as @MarcinJuraszek suggested in the comments or considering a different name for the DU case and the type.

Upvotes: 1

Related Questions