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

110 views Asked by At

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'

2

There are 2 answers

1
Tomas Petricek On BEST ANSWER

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.

0
Phillip Carter On

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 }

Related Questions in F#