I am trying to refactor some existing code into a more monodic approach. Existing code contains interfaces IXInterface
and numerics like int
and bool
. The numerics already have Zero
by default, the interfaces have it as a property gettor, but bool
and string
do not. One way out is to wrap bool and string in an interface, but this is cumbersome.
I figured if the F# language manages to extend the types for numerics, perhaps I can do it too for strings and bools for my particular situation.
module MyZero =
let inline get_zero () : ^a = ((^a) : (static member get_Zero : unit -> ^a)())
type System.String with
static member get_Zero() = System.String.Empty
type XR<'T when 'T : (static member get_Zero : unit -> 'T)> =
| Expression of (SomeObj -> 'T)
| Action of (int -> 'T)
| Value of 'T
| Empty
member inline this.Execute(x: SomeObj) : 'T =
match this with
| Value(v) -> v
| Expression(ex) -> ex x
| Action(a) -> a x.GetLocation
| Empty -> get_zero()
static member map f x=
match x with
| XR.Empty -> XR.Empty
| XR.Value v -> XR.Value <| f v
| XR.Action p -> XR.Action <| fun v -> f (p v)
| XR.Expression e -> XR.Expression <| fun x -> f (e x)
// etc
The above compiles fine, as long as I don't try to use it with strings or bools:
type WihtBool = XR<int> // succeeds
type WihtBool = XR<IXInterface> // succeeds
type WihtBool = XR<bool> // fails
type WithString = XR<string> // fails
The error is clear and correct (I have an extension method, which is not recognized for obvious reasons), I just don't know a non-intrusive way to get rid of it:
fails with "the type bool does not support the operator 'get_Zero'
fails with "the type string does not support the operator 'get_Zero'