Why does...
type IntDelegate = delegate of int -> unit
type ListHelper =
static member ApplyDelegate (l : int list) (d : IntDelegate) =
l |> List.iter (fun x -> d.Invoke x)
ListHelper.ApplyDelegate [1..10] (fun x -> printfn "%d" x)
not compile, when:
type IntDelegate = delegate of int -> unit
type ListHelper =
static member ApplyDelegate (l : int list, d : IntDelegate) =
l |> List.iter (fun x -> d.Invoke x)
ListHelper.ApplyDelegate ([1..10], (fun x -> printfn "%d" x))
does?
The only difference that is that in the second one, ApplyDelegate
takes its parameters as a tuple.
This function takes too many arguments, or is used in a context where a function is not expected
I haven't looked at the spec to confirm, but I am guessing that the implicit conversion from "lambda" to "named delegate type" only occurs in a "member invocations".
You can always make the conversion explicit:
ListHelper.ApplyDelegate [1..10] (IntDelegate(fun x -> printfn "%d" x))
(The error diagnostic is quite poor; I'll file a bug.)
EDIT:
For the wonks...
Yeah, the spec says
8.13.6 Type-directed Conversions at member invocations As described in Method Application Resolution (see §14.4), two type-directed conversions are applied at method invocations.
If a formal parameter is of delegate type DelegateType, and an actual argument is syntactically a function value (fun ...), then the parameter is interpreted as if it had been written new DelegateType(fun ...).
that lambdas get converted automagically to delegate types only at "member invocations". In the case of the curried member, the first argument passed is a member invocation, but then that returns a function value to apply the second argument, and function invocations do not have this implicit conversion rule.
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