zajer
zajer

Reputation: 803

How to implement an F# interface with a member returing an instance of that interface?

Let's say I have the following interface in F#:

type InterfaceA =
 abstract Magic : InterfaceA -> InterfaceA

How can I implement such interface? When I try to do it like this:

type MyTypeA = {x:int} with
 interface InterfaceA with
  member self.Magic another = 
   {x=self.x+another.x}

I get the error: This expression was expected to have type 'InterfaceA' but here has type 'MyTypeA'

Upvotes: 1

Views: 163

Answers (2)

Phillip Carter
Phillip Carter

Reputation: 5005

Posting as an alternative that's not really better, just different:

As of F# 6, you can also annotate the return type and the compiler will infer what you mean:

type InterfaceA =
 abstract Magic : InterfaceA -> InterfaceA
 abstract Value : int

type MyTypeA = 
  {x:int} 
  interface InterfaceA with
    member self.Value = self.x
    member self.Magic another : InterfaceA = 
      { x=self.x+another.Value }

Upvotes: 3

Tomas Petricek
Tomas Petricek

Reputation: 243051

To fix the type error, you need to explicitly cast the returned value to the InterfaceA type - unlike for example C#, F# does not do this automatically:

type InterfaceA =
 abstract Magic : InterfaceA -> InterfaceA
 abstract Value : int

type MyTypeA = 
  {x:int} 
  interface InterfaceA with
    member self.Value = self.x
    member self.Magic another = 
      { x=self.x+another.Value } :> InterfaceA

Note that your code also did not work because another was of type InterfaceA and so it did not have the x field you could access. To fix this, I added a member Value to the interface.

Upvotes: 7

Related Questions