The following code generates a compile-time error at myFunctions.Add fn
:
type IInterface = interface end
let myFunctions = ResizeArray<IInterface -> unit> ()
let add<'T when 'T :> IInterface> (fn: 'T -> unit) = myFunctions.Add fn
The error is "FS0001: Type mismatch. Excpeting a 'IInterface -> unit' but given a ''T -> unit' The type 'IInterface' does not match the type ''T'
"
This is puzzling to me for the obvious reason that I constrain 'T
to IInterface
.
There are no compile-time errors with the following code:
type IInterface = interface end
let myStuff = ResizeArray<IInterface> ()
let add<'T when 'T :> IInterface> (item: 'T) = myStuff.Add item
... so there is some property of function parameters that is incompatible with this approach.
What is that property, and is there a way to make my approach work?
F# has no implicit upcasting for object types. So, the following compiles:
let add<'T when 'T :> IInterface> (fn: IInterface -> unit) = myFunctions.Add fn
(Note that your case is not covered by the language guide's statement "Upcasting is applied automatically when you pass arguments to methods on an object type". 'T -> unit :> IInterface -> unit
is not an upcast. You would need upcasting earlier in the type checking process here, and that is not done in F#.)