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
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!"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With