Разница между именем функции F # и значением функции, указанным на это имя

#f# #fsxaml

#f# #fsxaml

Вопрос:

Я использую следующий фрагмент кода в приложении 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 работает только со вторым? Я бы (ошибочно?) думал, что это одно и то же.

Комментарии:

1. Если у кого-нибудь есть предложения по улучшению названия, я бы приветствовал это.

2. С моим опасным количеством неполных знаний F # я удивлен, что это вообще работает. Почему это не приводит к неопределенной рекурсии (ошибке)? Вы не указываете groupSelected на себя с помощью |> GroupSelected ?

3.@MarkusDeibel Если я чего-то не упустил, должно быть второе определение GroupSelected before let groupSelected (и оно должно принимать string и не SelectionChangedEventArgs принимать). Чтобы указывать на себя, это должно быть let rec groupSelected(e) ... and GroupSelected = groupSelected .

4. @MarkusDeibel Извините. Мой фрагмент кода был непонятен. У меня также есть DU с именем GroupSelected. Но это не имеет отношения к моему вопросу. Я обновил фрагмент кода.

Ответ №1:

Это одна из областей, где простые функциональные идеи немного усложняются из-за жизни в .Мир NET framework. F # действительно компилирует ваши groupSelected и GroupSelected двумя разными способами.

IntelliSense действительно сообщает вам об этом. В большинстве случаев это не то, о чем вам нужно беспокоиться, и вполне разумно рассматривать следующие два как одно и то же (и, что касается самого F #, так оно и есть):

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

Ключевое различие заключается в том, что они будут скомпилированы по-разному. Первое как метод, а второе как свойство, которое возвращает значение функции. Использование нотации C #:

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

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