given
open System
open System.Windows
open System.Windows.Input
open System.ComponentModel
type RelayCommand (canExecute:(obj -> bool), action:(obj -> unit)) =
let event = new DelegateEvent<EventHandler>()
interface ICommand with
[<CLIEvent>]
member x.CanExecuteChanged = event.Publish
member x.CanExecute arg = canExecute(arg)
member x.Execute arg = action(arg)
member x.CheckCanExecute (sender:obj) (eventArgs:EventArgs) = event.Trigger([| sender;eventArgs |])
how do I write a statically resolved type parameterized function that can satisfy a call to CheckCanExecute ?
while this function works it doesn't help me learn statically resolved type parameter syntax
let checkCanExecute (c:RelayCommand) = c.CheckCanExecute (box this) (EventArgs())
I expected this to work
let checkCanExecute (e:^a) = (^a: (member CheckCanExecute: sender:obj -> EventArgs -> unit ) (e, (box me),(EventArgs())))
but at the callsite
checkCanExecute addCommand
I get method or object constructor 'CheckCanExecute' not found (when using the 2nd definition, the 1st compiles just fine)
how do I define a class let binding (or member binding if that is a better way to get the job done) that uses Statically Resolved Type Parameters to be able to call the method on anything that has the matching method signature?
I think some of the difficulty here is caused by the fact that CheckCanExecute is defined as a curried function. For members, it is probably better to go with a tupled function (the way curried functions are compiled is tricky and it might be confusing the statically resolved constraint).
If you change the RelayCommand member as follows:
member x.CheckCanExecute (sender:obj, eventArgs:EventArgs) =
event.Trigger([| sender;eventArgs |])
And make your checkCanExecute an inline function that requires tupled function:
let inline checkCanExecute (e:^a) =
(^a: (member CheckCanExecute: obj * EventArgs -> unit ) (e, box me,(EventArgs())))
Then the following type checks:
checkCanExecute me
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