I have a vexing error.
type Animal =
abstract member Name : string
type Dog (name : string) =
interface Animal with
member this.Name : string =
name
let pluto = new Dog("Pluto")
let name = pluto.Name
The last line, specifically "Name" generates a compiler error saying that "the field, constructor or member 'Name' is not defined".
The workaround I've used is to write
let name = (pluto :> Animal).Name
However this is very annoying and creates a lot of visual noise. Is there something one can do in F# to just be able to resolve Name without telling the compiler explicitly that Name is a derived member from the Animal type?
In F#, when you implement an interface, it's an equivalent of explicit interface implementation in C#. That is, you can call the method through the interface, but not directly through the class.
F# reference article about interfaces suggests adding a method that does the upcasting to the type:
type Dog (name : string) =
member this.Name = (this :> Animal).Name
interface Animal with
member this.Name : string = name
Or, as suggested by Daniel, you can do it the other way around, which means you can avoid that cast:
type Dog (name : string) =
member this.Name = name
interface Animal with
member this.Name : string = this.Name
Also, the .Net convention for interface names is to start them with I
, so your interface should be called IAnimal
.
Another option is to use an abstract class instead of an interface:
[<AbstractClass>]
type Animal () =
abstract Name : string
type Dog (name) =
inherit Animal()
override dog.Name = name
let pluto = Dog("Pluto")
let name = pluto.Name
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