IT Share you

패턴 매칭과 가드의 차이점은 무엇입니까?

shareyou 2020. 12. 1. 20:01
반응형

패턴 매칭과 가드의 차이점은 무엇입니까?


저는 Haskell과 일반적으로 함수형 프로그래밍을 처음 접했습니다. 제 질문은 아주 기본적인 것입니다. 패턴 매칭과 가드의 차이점은 무엇입니까?

패턴 매칭을 이용한 기능

check :: [a] -> String
check [] = "Empty"
check (x:xs) = "Contains Elements"

가드를 사용한 기능

check_ :: [a] -> String
check_ lst
    | length lst < 1 = "Empty"
    | otherwise = "Contains elements"

나에게 그것은 패턴 매칭과 가드가 근본적으로 같은 것처럼 보입니다. 둘 다 조건을 평가하고 참이면 연결된 표현식을 실행합니다. 내 이해가 맞습니까?

이 예에서는 동일한 결과에 도달하기 위해 패턴 일치 또는 가드를 사용할 수 있습니다. 그러나 뭔가 중요한 것을 놓치고 있다는 것을 알 수 있습니다. 항상 하나를 다른 것으로 바꿀 수 있습니까?

누군가 가드보다 패턴 일치가 선호되고 그 반대의 경우 예를 들어 줄 수 있습니까?


사실, 그들은 근본적으로 상당히 다릅니다! 어쨌든 하스켈에서는 적어도.

Guards는 더 간단하고 유연합니다. 기본적으로 일련의 if / then 표현식으로 변환되는 특수 구문입니다. 가드에 임의의 부울 표현식을 넣을 수 있지만 일반 .NET으로는 할 수없는 작업을 수행하지 않습니다 if.

패턴 일치는 몇 가지 추가 작업을 수행합니다. 데이터를 분해 하는 유일한 방법 이며 범위 내에서 식별자바인딩 합니다. 가드가 if표현식 과 동일하다는 점 에서 패턴 일치는 case표현식 과 동일합니다 . 선언 (최상위 수준 또는 let표현식 과 같은 것 )도 패턴 일치의 한 형태이며 "정상"정의는 단일 식별자 인 사소한 패턴과 일치합니다.

패턴 일치는 또한 Haskell에서 실제로 발생하는 주요 방식 인 경향이 있습니다. 패턴에서 데이터를 분해하려는 시도는 평가를 강제하는 몇 안되는 요소 중 하나입니다.

그런데 실제로 최상위 선언에서 패턴 일치를 수행 할 수 있습니다.

square = (^2)

(one:four:nine:_) = map square [1..]

이것은 때때로 관련된 정의 그룹에 유용합니다.

GHC는 또한 ViewPatterns 확장제공합니다 . 바인딩 컨텍스트에서 임의의 함수를 사용한 다음 결과에 대한 패턴 일치를 사용할 수 있습니다. 물론 이것은 여전히 ​​평범한 것에 대한 통사론 적 설탕 일뿐입니다.


어디서 사용할 수있는 일상적인 문제에 대해서는 다음과 같은 대략적인 가이드가 있습니다.

  • 하나 또는 두 개의 생성자 깊이와 직접 일치 할 수있는 모든 항목에 대해 패턴 일치를 사용하십시오. 여기서 복합 데이터 전체에 대해서는 신경 쓰지 않지만 대부분의 구조는 신경 쓰십시오. @구문은 당신이 그것에 잠시 또한 변수 패턴 매칭에 전체 구조를 결합 할 수 있지만 하나 개의 패턴에 너무 많은 그 일을 신속 추한 읽을 수 있습니다.

  • 패턴에 깔끔하게 일치하지 않는 일부 속성을 기반으로 선택해야 할 때 가드를 사용 Int하십시오 ( 예 : 두 값을 비교하여 더 큰 것을 확인).

  • 큰 구조 내부 깊숙한 곳에서 몇 개의 데이터 만 필요하다면, 특히 구조를 전체적으로 사용해야하는 경우, 가드 및 접근 자 함수는 일반적으로 @및로 가득 찬 괴물 같은 패턴보다 더 읽기 쉽습니다 _.

  • 다른 패턴으로 표현 된 값에 대해 동일한 작업을 수행해야하지만이를 분류하기위한 편리한 술어를 사용하는 경우 가드가있는 단일 일반 패턴을 사용하는 것이 일반적으로 더 읽기 쉽습니다. 가드 세트가 완전하지 않은 경우 모든 가드가 실패하면 모든 가드가 다음 패턴 (있는 경우)으로 떨어집니다. 따라서 일반적인 패턴을 일부 필터와 결합하여 예외적 인 경우를 포착 한 다음 다른 모든 항목에 대해 패턴 일치를 수행하여 관심있는 세부 정보를 얻을 수 있습니다.

  • 패턴으로 사소하게 확인할 수있는 것들에 대해 가드를 사용하지 마십시오. 빈 목록을 확인하는 것이 고전적인 예이므로 패턴 일치를 사용하십시오.

  • 일반적으로 의심스러운 경우 기본적으로 패턴 일치를 고수하면 일반적으로 더 좋습니다. 패턴이 정말 추악하거나 복잡해지기 시작하면 그만두고 어떻게 작성할 수 있는지 생각해보십시오. 가드를 사용하는 것 외에도 다른 옵션에는 하위 표현식을 별도의 함수로 추출하거나 case일부 패턴 일치를 기본 정의 밖으로 밀어 내기 위해 함수 본문에 표현식을 넣는 것이 포함됩니다.


나에게 그것은 패턴 매칭과 가드가 근본적으로 같은 것처럼 보입니다. 둘 다 조건을 평가하고 참이면 연결된 표현식을 실행합니다. 내 이해가 맞습니까?

좀 빠지는. 첫 번째 패턴 일치는 임의의 조건을 평가할 수 없습니다. 주어진 생성자를 사용하여 값이 생성되었는지 여부 만 확인할 수 있습니다.

두 번째 패턴 일치는 변수를 바인딩 할 수 있습니다. 패턴이 그래서 동안 []가드에 해당 될 수있다 null lst(즉 해당되지 않을 것 때문에 길이를 사용하지 않는 - 그 나중에 더), 패턴은 x:xs가장 확실하게 가드에 해당되지 않습니다 not (null lst)때문에 패턴 변수 바인딩 xxs가드가하는, 아니.

사용에 대한주의 사항 length: 사용 length, 그것은 걸릴 전체 목록을 통해 갈 필요 길이를 계산하기 때문에 목록이 비어 있는지 여부를 확인하기는 아주 나쁜 방법입니다 O(n)단지 목록이 비어 있는지 여부를 확인하는 동안 시간하는 소요 O(1)시간을 null나 패턴 매칭. 추가로 'length'를 사용하면 일반 목록에서 작동하지 않습니다.


우선 가드 내에 부울 표현식을 넣을 수 있습니다.

:

리스트 이해와 마찬가지로, 부울 표현식은 패턴 가드간에 자유롭게 혼합 될 수 있습니다. 예를 들면 :

f x | [y] <- x
    , y > 3
    , Just z <- h y
    = ...


최신 정보

차이점에 대한 Learn You a Haskell 의 멋진 인용문이 있습니다 .

Whereas patterns are a way of making sure a value conforms to some form and deconstructing it, guards are a way of testing whether some property of a value (or several of them) are true or false. That sounds a lot like an if statement and it's very similar. The thing is that guards are a lot more readable when you have several conditions and they play really nicely with patterns.


In addition to the other good answers, I'll try to be specific about guards: Guards are just syntactic sugar. If you think about it, you will often have the following structure in your programs:

f y = ...
f x =
  if p(x) then A else B

That is, if a pattern matches, it is followed right after by a if-then-else discrimination. A guard folds this discrimination into the pattern match directly:

f y = ...
f x | p(x) = A
    | otherwise = B

(otherwise is defined to be True in the standard library). It is more convenient than an if-then-else chain and sometimes it also makes the code much simpler variant-wise so it is easier to write than the if-then-else construction.

In other words, it is sugar on top of another construction in a way which greatly simplifies your code in many cases. You will find that it eliminates a lot of if-then-else chains and make your code more readable.

참고URL : https://stackoverflow.com/questions/4156727/what-is-the-difference-between-pattern-matching-and-guards

반응형