F# явное соответствие по сравнению с синтаксисом функций

Первый пример не ориентирован на многопотоковое исполнение - если два потока называют getInstance одновременно, который статичный будет ЛАВАШЕМ. Некоторая форма взаимного исключения помогла бы.

78
задан Benjol 3 December 2009 в 10:23
поделиться

6 ответов

Версия соответствия называется "выражением сопоставления с образцом". Версия функции называется «функцией сопоставления с образцом». Найдено в разделе 6.6.4 спецификации .

Использование одного над другим - вопрос стиля. Я предпочитаю использовать только версию функции, когда мне нужно определить функцию, которая является только оператором соответствия.

51
ответ дан 24 November 2019 в 10:31
поделиться

Плюс второго синтаксиса в том, что при использовании в лямбде он может быть немного более кратким и читаемым.

List.map (fun x -> match x with | 1 -> "one" | _ -> "not one") [0;1;2;3;1]

vs

List.map (function 1 -> "one" | _ -> "not one") [0;1;2;3;1]
72
ответ дан 24 November 2019 в 10:31
поделиться

В вашем случае они делают то же самое - ключевое слово function действует как комбинация ключевого слова fun (для создания анонимной лямбды) за которым следует ключевое слово match .

Таким образом, технически это одно и то же, с добавлением забавы :

let foo1 = fun x ->
    match x with
    | 1 -> "one"
    | _ -> "not one"

let foo2 = function
    | 1 -> "one"
    | _ -> "not one"
12
ответ дан 24 November 2019 в 10:31
поделиться

Версия функции - это сокращение от синтаксиса полного соответствия в особом случае, когда оператор соответствия представляет собой всю функцию, а функция имеет только один аргумент (кортежи считаются как один). Если вы хотите иметь два аргумента, вам нужно использовать синтаксис полного соответствия *. Вы можете увидеть это в типах следующих двух функций.

//val match_test : string -> string -> string
let match_test x y = match x, y with
                        | "A", _ -> "Hello A"
                        | _, "B" -> "Hello B"
                        | _ -> "Hello ??"

//val function_test : string * string -> string                   
let function_test = function
                        | "A", _ -> "Hello A"
                        | _, "B" -> "Hello B"
                        | _ -> "Hello ??"

Как вы можете видеть, версия соответствия принимает два отдельных аргумента, тогда как версия функции принимает один кортежный аргумент. Я использую версию функции для большинства функций с одним аргументом, так как считаю, что синтаксис функции выглядит чище.

* Если вы действительно хотите, вы можете получить версию функции с правильной сигнатурой типа, но, на мой взгляд, это выглядит довольно некрасиво - см. пример ниже.

//val function_match_equivalent : string -> string -> string
let function_match_equivalent x y = (x, y) |> function
                                                | "A", _ -> "Hello A"
                                                | _, "B" -> "Hello B"
                                                | _ -> "Hello ??"
20
ответ дан 24 November 2019 в 10:31
поделиться

два синтаксиса эквивалентны. Большинство программистов выбирают один или другой, а затем используют его последовательно.

Первый синтаксис остается более читаемым, когда функция принимает несколько аргументов перед началом работы.

4
ответ дан 24 November 2019 в 10:31
поделиться

Для полноты картины я только что перешел на страницу 321 из Expert FSharp :

"Примечание, листинг 12-2 использует форму выражения function pattern-rules -> expression . Это эквивалентно (fun x -> match x with pattern-rules -> expression) и особенно удобно как способ определения функций, работающих непосредственно над размеченными объединениями. "

9
ответ дан 24 November 2019 в 10:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: