Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Records satisfying implicit interface w/o re-implementing

Seeing a record already has a public Getter/(Setter) for its fields, is it possible to specify that a record satisfies a matching interface without re-implementing it?

For example:

type IText = 
    abstract text : string with get,set

type TextRec = 
{ 
mutable text : string
}

Now seeing the Record already implements this interface implicitly, I'd like to put an "inherit IText" or "interface IText" (with no body) on the record, but it appears I can't do that. As it is, I believe I have to re-implement the interface by adding this to the record:

interface IText with
    member this.text
        with get()  = this.text
        and set(v)  = this.text <- v

thanks

like image 444
TheLazyDogsBack Avatar asked Mar 18 '23 12:03

TheLazyDogsBack


1 Answers

F# currently does not support implicit interface implementations (not even for classes), but it is one of the frequently requested features, so it might happen in the future. I certainly see why this would be useful.

I don't think there is any good workaround for this - the best option is probably to write the additional piece of code needed to implement the interface.

If you wanted to be adventurous, you could try writing a "wrapping" function that creates an interface implementation from a value that provides the required members. Using static member constraints, you can require the members to be there (without actually implementing the interface):

type IText = 
  abstract Text : string with get, set

let inline wrap (a:^T) =
  { new IText with
      member x.Text 
        with get() = (^T : (member Text : string) (a)) 
        and set(v) = (^T : (member set_Text : string -> unit) (a, v)) }

Static member constraints (used in the implementation of wrap) are mainly useful for generic numerical computations, so this is a bit of a stretch (and certainly an advanced F# feature), but it does the trick:

type Rect = { mutable Text : string }
let i = wrap { Text = "Hi" }
i.Text <- i.Text + " there!"
like image 59
Tomas Petricek Avatar answered Mar 31 '23 18:03

Tomas Petricek