Извините за расплывчатое название, но часть этого вопроса заключается в том, как называются эти два стиля синтаксиса:
let foo1 x =
match x with
| 1 -> "one"
| _ -> "not one"
let foo2 = function
| 1 -> "one"
| _ -> "not one"
Другая часть заключается в том, какая разница между ними, и когда я хотел бы использовать тот или другой?
Плюс второго синтаксиса в том, что при использовании в лямбде он может быть немного более кратким и читабельным.
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]
источник
Версия функции - это сокращение от синтаксиса полного соответствия в особом случае, когда оператор соответствия представляет собой всю функцию, а функция имеет только один аргумент (кортежи считаются как один). Если вы хотите иметь два аргумента, вам нужно использовать синтаксис полного соответствия *. Вы можете увидеть это в типах следующих двух функций.
//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 ??"
источник
В вашем случае они делают то же самое -
function
ключевое слово действует как комбинацияfun
ключевого слова (для получения анонимной лямбды), за которым следуетmatch
ключевое слово.Так что технически это одно и то же, с добавлением
fun
:let foo1 = fun x -> match x with | 1 -> "one" | _ -> "not one" let foo2 = function | 1 -> "one" | _ -> "not one"
источник
fun
есть технически определяется в терминахfunction | _ -> ...
?fun x y -> ...
было быfun x -> fun y -> ...
, а потомfun x -> ...
было быfunction | x -> ...
. Вот почему вы можете выполнять сопоставление с образцом,fun
напримерfun (x::xs) -> ...
.Для полноты картины я только что перешел на страницу 321 Expert FSharp :
источник
Функция допускает только один аргумент, но позволяет сопоставление с образцом, в то время как fun - это более общий и гибкий способ определения функции. Взгляните здесь: http://caml.inria.fr/pub/docs/manual-ocaml/expr.html
источник
Два синтаксиса эквивалентны. Большинство программистов выбирают один или другой и затем последовательно его используют.
Первый синтаксис остается более читабельным, если функция принимает несколько аргументов перед началом работы.
источник
Это старый вопрос, но я брошу свои 0,02 доллара.
В целом мне больше нравится эта
match
версия, поскольку я пришел из мира Python, где «явное лучше, чем неявное».Конечно, если требуется информация о типе параметра,
function
версию использовать нельзя.OTOH Мне нравится аргумент, который приводит,
Stringer
поэтому я начну использоватьfunction
в простых лямбдах.источник