none
Implementation in F# Interface definition??? RRS feed

  • Question

  • So I'm new to F#, and reading a couple of different tutorials, and I was surprised to see it mentioned that F# interface definitions can actually include default implementations for member methods (making them act like virtual methods).  This is mentioned both here:

    http://www.tutorialspoint.com/fsharp/fsharp_interfaces.htm

    and here:

    https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/interfaces-%5Bfsharp%5D

    I find this rather odd as one of the defining characteristics of an interface is that it contains no implementation.  But what's even more odd, is that I can't seem to find any more information on this anywhere on the web.  Those two pages I link merely mention that this is a possibility, but don't go into any detail or provide any examples.

    So how does this work?  If I provide a default implementation for an interface function, how does it get used?  Can I simply neglect to implement that method when implementing the interface in a class and the default implementation will be used?  Can I call the default implementation directly from my override implementation with the base keyword?  What happens if I define such an interface in F#, then try to implement it in a C# class definition?  Any established use cases for this behavior?

    And why isn't any of this discussed anywhere???



    Tuesday, June 14, 2016 9:48 PM

All replies

  • I'm not sure what is going on here; it  may be someone has become confused by the very similar syntax for abstract classes.

    Trying (in F# 3.0, 3.1 and 4.0)

    type IPrintable = interface
       abstract member Print : unit -> unit
       default this.Print () = printfn "Hello, world!"
    end
    
    type SomeClass1(x: int, y: float) =
       interface IPrintable with
          member this.Print() = printfn "%d %f" x y
    
    type SomeClass2() =
        member this.Action () = printfn "act"
        interface IPrintable
    
    let x1 = new SomeClass1(1, 2.0)
    (x1 :> IPrintable).Print()
    
    let x2 = SomeClass2()
    (x2 :> IPrintable).Print()
    
    System.Console.ReadKey() |> ignore

    yields

         default this.Print () = printfn "Hello, world!"
      ----------------^^^^^
    
    stdin(5,17): error FS0867: Interfaces cannot contain definitions of member overrides

    Changing the definition of IPrintable to

    type IPrintable = 
       abstract member Print : unit -> unit
       default this.Print () = printfn "Hello, world!"

    defines an abstract class instead, and we get

         interface IPrintable with
      -------------^^^^^^^^^^
    
    stdin(30,14): error FS0887: The type 'IPrintable' is not an interface type
    as expected from the consumers.

    Sunday, June 19, 2016 10:08 AM
  • Hello, Jesse!

    You can not describe the implementation of the method in an interface declaration.

    This is only possible for abstract classes.

    Through this approach, including,ensured compatibility between C# and F #.

    However,in Haskell has a similar opportunity. If you're interested,I can tell:

    class Eq a where
    	(==), (/=) :: a -> a -> Bool --abstract
    	x /= y = not (x == y)        --default implementation
    	x == y = not (x /= y)        --default implementation
    instance Eq Bool where
    	(==) True True = True
    	(==) False False = True
    	(==) _ _ = False 
    Wednesday, July 13, 2016 8:06 AM