F # 명시 적 일치 대 함수 구문


88

모호한 제목에 대해 죄송하지만이 질문의 일부는 다음 두 가지 구문 스타일이 무엇인지에 대한 것입니다.

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

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

다른 부분은 둘 사이에 어떤 차이가 있으며 언제 둘 중 하나를 사용하고 싶습니까?

답변:


57

일치 버전을 "패턴 일치 표현식"이라고합니다. 함수 버전을 "패턴 일치 함수"라고합니다. 사양 의 섹션 6.6.4에서 찾을 수 있습니다.

다른 하나를 사용하는 것은 스타일의 문제입니다. 나는 단지 match 문인 함수를 정의해야 할 때만 함수 버전을 사용하는 것을 선호합니다.


감사합니다. F #을 사용한 Functional Programming은 function 키워드의 사용이 패턴 일치 기능임을 나타내지 만이 답변과 OP는 두뇌가 막힌 순간을 명확히합니다.
octopusgrabbus

링크가 끊어진 것 같습니다.
MattMS

83

두 번째 구문의 장점은 람다에서 사용할 때 좀 더 간결하고 읽기 쉽다는 것입니다.

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]

23

함수 버전은 match 문이 전체 함수이고 함수에 단일 인수 만있는 특수한 경우에 전체 일치 구문의 약어입니다 (튜플은 하나로 계산 됨). 두 개의 인수를 원하면 전체 일치 구문 *을 사용해야합니다. 다음 두 가지 기능의 유형에서이를 확인할 수 있습니다.

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

12

그들은 귀하의 경우에 동일한 일을합니다- function키워드는 fun키워드 (익명 람다를 생성하기 위해) 와 키워드 의 조합처럼 작동 match합니다.

따라서 기술적으로이 두 가지는 동일하며 다음을 추가합니다 fun.

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

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

1
실제로 다른 방법 funfunction | _ -> ...아닌가? 즉, 기술적으로는
Pavel Minaev

1
구체적으로, fun x y -> ...fun x -> fun y -> ..., 다음 fun x -> ...이 될 것입니다 function | x -> .... 그것은 당신이 패턴 매칭을 할 수있는 이유 fun예 - fun (x::xs) -> ....
Pavel Minaev

10

완전성을 위해 Expert FSharp의 321 페이지에 도달했습니다 .

"참고, 목록 12-2는 표현식 형식을 사용합니다 function pattern-rules -> expression. 이는 (fun x -> match x with pattern-rules -> expression)구별 된 공용체에 대해 직접 작동하는 함수를 정의하는 방법으로 특히 편리합니다."


6

function 은 하나의 인수 만 허용하지만 패턴 일치를 허용하는 반면 fun 은 함수를 정의하는보다 일반적이고 유연한 방법입니다. 여기를보세요 : http://caml.inria.fr/pub/docs/manual-ocaml/expr.html


왜 마지막 논증이 아니라 단 하나의 논증 만 말합니까? 둘 이상의 인수를 갖고 "함수"를 사용할 수 있습니다. 이것은 고차 함수 해석입니까?
symbiont

4

두 구문은 동일합니다. 대부분의 프로그래머는 둘 중 하나를 선택하고 일관되게 사용합니다.

첫 번째 구문은 함수가 작업을 시작하기 전에 여러 인수를 허용 할 때 더 읽기 쉽습니다.


2

이것은 오래된 질문이지만 $ 0.02를 던질 것입니다.

일반적으로 나는 match"명시적인 것이 암시적인 것보다 낫다"는 파이썬 세계에서 왔기 때문에 더 나은 버전을 좋아합니다 .

물론 매개 변수에 대한 유형 정보가 필요한 경우 function버전을 사용할 수 없습니다.

OTOH의 주장이 마음에 들어서 간단한 람다로 Stringer시작하겠습니다 function.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.