Подтвердить что ты не робот

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

Извините за неопределенное название, но часть этого вопроса - это то, что называются этими двумя стилями синтаксиса:

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

let foo2 = function 
    | 1 -> "one" 
    | _ -> "not one"

Другая часть - какая разница между этими двумя, и когда я хотел бы использовать один или другой?

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

против

List.map (function 1 -> "one" | _ -> "not one") [0;1;2;3;1]

Ответ 3

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

//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 ??"

Ответ 4

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

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

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

let foo2 = function
    | 1 -> "one"
    | _ -> "not one"

Ответ 5

Просто ради полноты, я просто добрался до страницы 321 Expert FSharp:

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

Ответ 6

функция допускает только один аргумент, но позволяет сопоставлять шаблоны, а fun - более общий и гибкий способ определения функции. Посмотрите здесь: http://caml.inria.fr/pub/docs/manual-ocaml/expr.html

Ответ 7

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

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

Ответ 8

Это старый вопрос, но я брошу свои $0,02.

В общем, мне нравится версия match, так как я пришел из мира Python, где "явное лучше, чем неявное".

Конечно, если информация о типе параметра не нужна, версия function не может быть использована.

OTOH Мне нравится аргумент, сделанный Stringer, поэтому я начну использовать function в простых lambdas.