Search code examples
f#fsxaml

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


I'm using the following code snippet in a WPF / FsXaml application:

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

let GroupSelected = groupSelected

When I mouse-over groupSelected, Visual Studio shows the following:

val groupSelected: e:SelectionChangedEventArgs -> ClientGroupEvent

It is slightly different for GroupSelected:

val GroupSelected: (SelectionChangedEventArgs -> ClientGroupEvent)

I have noticed this difference before in other contexts and never thought much of it. If I want to invoke either one, the syntax in my code is the same... groupSelected(e) and GroupSelected(e) both compile fine.

However, when I try to use these two from XAML only this works:

{x:Static local:EventConverters.GroupSelected}

This does not work:

{x:Static local:EventConverters.groupSelected}

What is the difference between those two such that XAML Static extension only works with the second? I would have (mistakenly?) thought they were the same thing.


Solution

  • This is one of the areas where simple functional ideas are made a bit more complicated by living in the .NET framework world. F# indeed compiles your groupSelected and GroupSelected in two different ways.

    The IntelliSense does tell you this. Most of the time, this is not something you need to worry about, and it is quite sensible to see the following two as the same thing (and, as far as F# itself is concerned, they are):

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

    The key difference is that the two will be compiled diferently. The first one as a method and the second one as a property that returns a function value. Using C# notation:

    // groupSelected is compiled as a method:
    ClientGroupEvent groupSelected(SelectionChangedEventArgs e);
    
    // GroupSelected is compiled as a property:
    FSharpFunc<SelectionChangedEventArgs, ClientGroupEvent> GroupSelected { get; }