hubFS: THE place for F#

. . . are you on The Hub?
Welcome to hubFS: THE place for F# Sign in | Join | Help
in Search

Partially Implemented Type with Interface Compatibility?

Last post 06-27-2008, 20:22 by allenlooplee. 2 replies.
Sort Posts: Previous Next
  •  06-27-2008, 1:38 6214

    Partially Implemented Type with Interface Compatibility?

    Hi, I have been learning & playing with F# for a couple of weeks. Suppose I have an interface as follows:

    type IProduct =
        abstract Name: string
        abstract Work: unit -> unit

    Now I want to create a type containing a default implementation for Work but leaving Name abstract. Here's my attempt:

    [<AbstractClass>]
    type SomeProduct =
        abstract Name: string
        abstract Work: unit -> unit
        default this.Work() = printfn "%s is working..." this.Name

    Obviously, SomeProduct is not compatible with IProduct and the compatibility is what I want, but I don't know how to implement IProduct for SomeProduct.

    With C#, it will be super easy:

    interface IProduct
    {
        string Name { get; }
        void Work();
    }

    abstract class SomeProduct : IProduct
    {
        public abstract string Name { get; }

        public virtual void Work()
        {
            Console.WriteLine("{0} is working...", Name);
        }
    }

    It was said in this community that the only way F# provides to implement an interface is equivalent to C# explicit interface implementation. Then how can I redirect the call to IProduct.Name to SomeProduct.Name?

    [<AbstractClass>]
    type SomeProduct =
        abstract Name: string
        abstract Work: unit -> unit
        default this.Work() = printfn "%s is working..." this.Name
       
        interface IProduct with
        (* What should be added here? *)

    Thanks in advance!


    Allen Lee, C# MVP
    http://allenlee.spaces.live.com/
  •  06-27-2008, 16:29 6223 in reply to 6214

    Re: Partially Implemented Type with Interface Compatibility?

    Hi there,

    F# 1.9.4 only supports "explicit" interface implementations. Implicit interface implementations have been requested and it is likely we'll support them in a future version of F#.

    However, it's also worth learning other techniques for partial implementations of objects. For example, you can simulate many partial implementation techniques through function parameters, object expressions and/or optional arguments. For example, consider the following



    type IProduct =
        abstract Name: string
        abstract Work: unit -> unit

    let BuildProduct(name) =
        { new IProduct with
            member x.Name = name
            member x.Work() = printfn "work" }

    Here an object expression has been used for your original request (Name variable, Work fixed). More generally, a object builder parameterized by optional arguments with sensible defaults can be quite flexible :

    type ProductBuilders =
        static member BuildProduct(?name,?work) =
            { new IProduct with
                member x.Name = match name with None -> "" | Some n -> n
                member x.Work() = match work with None -> () | Some f -> f() }

    ProductBuilders.BuildProduct(name="1")
    ProductBuilders.BuildProduct(work=(fun () -> printfn "work"))
    ProductBuilders.BuildProduct(name="3",work=(fun () -> printfn "work"))

    You may also define types that implement an interface in a similar way:



    type Product(?name,?work) =
        interface IProduct with
                member x.Name = match name with None -> "" | Some n -> n
                member x.Work() = match work with None -> () | Some f -> f() 

    let p = (Product(name="1") :> IProduct)

    Kind regards

    don

     

  •  06-27-2008, 20:22 6232 in reply to 6223

    Re: Partially Implemented Type with Interface Compatibility?

    Thanks don! I have been reading your book, Expert F#, these days and tried the functional ways to meet the need. Object expression is one of my favorite feature of F#, and I just wonder whether there will be an OO way to express this idea. Wink [;)]

    Best wishes

    Allen Lee


    Allen Lee, C# MVP
    http://allenlee.spaces.live.com/
View as RSS news feed in XML
Powered by Community Server, by Telligent Systems