F# 函数名称和指向该名称的函数值之间的区别

Difference between an F# function name and a function value pointed at that name

我在 WPF/FsXaml 应用程序中使用以下代码片段:

let groupSelected(e: SelectionChangedEventArgs) =
    e.AddedItems
    |> Seq.cast<string>
    |> Seq.head
    |> SelectedGroupChanged

let GroupSelected = groupSelected

当我将鼠标悬停在 groupSelected 上时,Visual Studio 显示以下内容:

val groupSelected: e:SelectionChangedEventArgs -> ClientGroupEvent

GroupSelected略有不同:

val GroupSelected: (SelectionChangedEventArgs -> ClientGroupEvent)

我以前在其他情况下就注意到了这种差异,但从未想过太多。如果我想调用其中任何一个,我的代码中的语法是相同的... groupSelected(e)GroupSelected(e) 都编译得很好。

但是,当我尝试使用 XAML 中的这两个时,只有这个有效:

{x:Static local:EventConverters.GroupSelected}

有效:

{x:Static local:EventConverters.groupSelected}

这两者之间有什么区别 XAML 静态扩展仅适用于第二个?我会(错误地?)认为它们是同一回事。

这是生活在 .NET 框架世界中使简单的功能性想法变得更加复杂的领域之一。 F# 确实以两种不同的方式编译您的 groupSelectedGroupSelected

IntelliSense 会告诉您这一点。大多数时候,这不是您需要担心的事情,将以下两个视为同一事物是非常明智的(并且,就 F# 本身而言,它们是):

val groupSelected: e:SelectionChangedEventArgs -> ClientGroupEvent
val GroupSelected: (SelectionChangedEventArgs -> ClientGroupEvent)

主要区别在于两者的编译方式不同。第一个作为方法,第二个作为 属性 即 returns 函数值。使用 C# 表示法:

// groupSelected is compiled as a method:
ClientGroupEvent groupSelected(SelectionChangedEventArgs e);

// GroupSelected is compiled as a property:
FSharpFunc<SelectionChangedEventArgs, ClientGroupEvent> GroupSelected { get; }