I’m trying to define a generic addition operator for a wrapper class. So far I have this: (simplified from the actual code)
type Wrap<'a> =
| Wrap of 'a
static member inline (+) (Wrap x, Wrap y) = Wrap (x + y)
let inline addSelf x = x + x
and indeed it works:
let i = addSelf (Wrap 1) // returns Wrap 2
let f = addSelf (Wrap 1.) // returns Wrap 2.0
but the following alternative to addSelf does not compile
let inline addSelf' (Wrap x) = (Wrap x) + (Wrap x) // compile error
giving error FS0193: A type parameter is missing a constraint ‘when ( ^a or ^?15169) : (static member ( + ) : ^a * ^?15169 -> ^?15170)’
Why does the more restricted addSelf’ not work when addSelf works fine? Thanks!
If you look at the definition of Wrap in FSI, you will see that the static (+) operator is defined only for types that support the restriction, yet Wrap itself is defined for any types.
When write the first version, the type inference adds that restriction for you… but your second version allows any type for x (even for x that do not support the static (+) operator).
I.e. the second version suggest that it is possible to write a function that would support any type of Wrap<‘T> although there’s no guarantee ‘T supports the + operator.
edit:
As Tomas pointed out, it’s possible but you have to use a special syntax that defines which member to call, the following works: