如何定义此静态解析的类型参数?

Mas*_*low 3 f#

特定

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  |])
Run Code Online (Sandbox Code Playgroud)

如何编写一个可以满足调用的静态解析类型参数化函数CheckCanExecute

虽然这个功能有效,但它无法帮助我学习静态解析的类型参数语法

let checkCanExecute (c:RelayCommand) = c.CheckCanExecute (box this) (EventArgs())

我希望这可行

let checkCanExecute (e:^a) = (^a: (member CheckCanExecute: sender:obj -> EventArgs -> unit ) (e, (box me),(EventArgs())))

但是在呼叫现场 checkCanExecute addCommand

找不到方法或对象构造函数'CheckCanExecute'(当使用第二个定义时,第一个编译就好了)

如何let使用静态解析类型参数定义类绑定(或成员绑定,如果这是更好的完成工作的方法),以便能够在具有匹配方法签名的任何内容上调用该方法?

Tom*_*cek 6

我认为这里的一些困难是由CheckCanExecute定义为咖喱函数的事实引起的。对于成员而言,最好使用元组函数(咖喱函数的编译方式比较棘手,并且可能使静态解析约束变得混乱)。

如果RelayCommand按以下方式更改成员:

 member x.CheckCanExecute (sender:obj, eventArgs:EventArgs) =  
   event.Trigger([| sender;eventArgs  |])
Run Code Online (Sandbox Code Playgroud)

并使您checkCanExecuteinline函数需要元组函数:

let inline checkCanExecute (e:^a) = 
  (^a: (member CheckCanExecute: obj * EventArgs -> unit ) (e, box me,(EventArgs())))
Run Code Online (Sandbox Code Playgroud)

然后,以下类型检查:

checkCanExecute me
Run Code Online (Sandbox Code Playgroud)


pia*_*ste 6

如果您想使用SRTP,则无法以普通方式进行方法.成员调用语法无法一次处理多个curried参数.

要么像Tomas建议的那样使用.NET风格的tupled声明,要么你必须在表单中明确地写出currying member x.f a = fun b -> fun c -> ....

在你的例子中,这意味着:

type RelayCommand
    // ...
    member x.CheckCanExecute sender = fun eventArgs -> 
        event.Trigger([| sender;eventArgs  |])        

let inline checkCanExecute (e:^a) = 
    (^a: (member CheckCanExecute: obj -> (EventArgs -> unit)) (e, (box e)) ) <| EventArgs()
Run Code Online (Sandbox Code Playgroud)