简体   繁体   中英

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'

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.

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 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM