F# How to use an interface in a separate module
here is my module with my interfaces
//open statements omitted for brevity module DrawingInterfaces = ///gets a string representation of the SVG code representation of the object type IRepresentable_SVG = abstract member getSVGRepresenation : unit -> string //other interfaces omitted for brevity
Now within the same namespace and physical folder also I have this:
type lineSet (x1off,x2off,y1off,y2off,x1,x2,y1,y2,rot,rotOff,count) = //tons of member vals omitted for brevity member val x1Start = x1 with get, set interface DrawingInterfaces.IRepresentable_SVG with member __.getSVGRepresenation() = let mutable svg = "" let mutable currentx1 = x1Start svg
This used to give me 2 errors, before I was using the __. notation for the member. The first error was on the interface line. And a second on the member line. The errors were respectively:
The type 'IRepresentable_SVG' is not defined This instance member needs a parameter to represent the object being invoked.
I was able to fix the first one by changing the file order. Thanks to John Palmer. The second one is nearly fixed./
After using the __ . notation I was able to get rid of the second error. However, now a new error pops up when I try to use type members in my interface implementation.
let mutable currentx1 = x1Start
x1Start shows as not being defined. I need to be able to use values stored in my other members within my implementation.
Let's first make it work and then point to your problems. I define below 2 separate modules in 2 separate .fs files within the same namespace Example for interface definition in module Example.DrawingInterfacesand interface implementation in module Example.UseInterface and also a console app that will use the interface from third (implicit) module Program. In my project correspondent code files are in the following order: DefInterface.fs, UseInterface,fs, Program.fs (I also made few idiomatic styling changes and more brevity omissions)
namespace Example module DrawingInterfaces = type IRepresentable_SVG = abstract member GetSVGRepresenation : unit -> string
namespace Example module UseInterface = type LineSet (x1) = member val X1Start = x1 with get, set interface DrawingInterfaces.IRepresentable_SVG with member __.GetSVGRepresenation() = "test" + " " + __.X1Start.ToString()
open Example open System [<EntryPoint>] let main argv = let lineSet = UseInterface.LineSet(5) let example : DrawingInterfaces.IRepresentable_SVG = lineSet :> _ example.GetSVGRepresenation() |> printfn "%A" lineSet.X1Start <- 10 example.GetSVGRepresenation() |> printfn "%A" 0
Compile, run and make sure it works.
Now to problems in your code:
- first error message stems from the need to refer to the full implemented interface name in UseInterface.fs, which is Example.DrawingInterfaces.IRepresentable_SVG although as both modules belong to the same namespace the Example prefix may be omitted
- second error message points to the need of using instance method in implementation class UseInterface.LineSet, which is achieved by prepending self-identifier __. to the method signature
Finally, notice the usage of your interface in Program.fs that imports namespace, provides module names for definition and implementation respectively, and also explicitly casts implementation LineSet to IRepresentable_SVG.
EDIT: I've added X1Start property to the original LineSet to show how it can be used from interface implementation per question author's request. Now self-id __. is more involved and probably using self. or even this. instead would make more sense.