It seems that the p argument in printPerson function can't be inferred to be Person, but intelisense shows for both of printPerson calls that I'm passing p : Person. Help me understand what I'm doing wrong please?
type Person (name:string) =
member e.Name = name
type EmployeeNode =
| Leader of Person * int * list<EmployeeNode>
| Employee of Person * int
let printPerson level p =
printfn "%s %s" <| String.replicate (level) "#" <| p.Name
let rec print node =
match node with
| Employee(p, level) -> printPerson level p
| Leader(p, level, nodes) ->
printPerson level p
List.iter print nodes
Multiple types could have a member this.Name
, even if they don't in this example, so the compiler doesn't know that you meant Person
. Say for example you had
type Person (name : string) =
member this.Name = name
type School (name : string, address : string) =
member this.Name = name
member this.Address = address
let printName x = printfn "%s" x.Name // This is a type error.
The compiler can't tell which you meant - Person
or School
. It doesn't matter if you haven't defined another type with a member of the same name, the compiler still won't take the type because things like type extensions can add members onto types after compilation.
Intellisense knows the types you're trying to pass when you call the function, but that's not the same as the compiler enforcing type-safety. In general, any function which accesses class methods or members will need a type annotation for that class.
To fix your example, you just need to change to
let printPerson level p =
to
let printPerson level (p : Person) =
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With