패턴 매칭
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
패턴 매칭은 주어진 데이터를 특정 패턴과 비교하여 일치하는 부분을 찾는 기술로, 초기 프로그래밍 언어인 COMIT, SNOBOL 등에서 시작되었다. ML, Haskell, Scala, F#과 같은 함수형 프로그래밍 언어에서 함수 인수 패턴 매칭 기능을 제공하며, 텍스트 편집기, 수식 처리 시스템, Mathematica 등 다양한 분야에서 활용된다. SNOBOL4는 패턴을 일급 객체로 사용하여 문자열 조작에 강력한 기능을 제공한다.
더 읽어볼만한 페이지
- 검색 - 색인
색인은 책, 데이터베이스 등에서 특정 항목의 위치를 쉽게 찾도록 돕는 도구이며, 서적 색인은 19세기 말 상세한 챕터 제목을 포함하는 형태로 발전했고, 데이터베이스와 인터넷에서도 활용되며, 일관성, 관련성, 정확성을 갖춰 전문적인 과정을 통해 작성된다. - 검색 - 최근접 이웃 탐색
최근접 이웃 탐색은 다차원 공간에서 주어진 질의와 가장 유사한 데이터를 찾는 최적화 문제로, 데이터 압축, 데이터 마이닝, 기계 학습 등 다양한 분야에서 활용되며, 효율적인 탐색을 위해 다양한 알고리즘이 개발되고 있고, 개인 정보 보호 및 데이터 편향성과 같은 윤리적 문제에 대한 고려도 중요해지고 있다. - 구문 분석 - 낱말 분석
낱말 분석은 자연어 처리와 컴파일 과정에서 문자열을 토큰으로 분해하는 과정으로, 렉서의 첫 단계로서 소스 코드에서 변수, 연산자 등을 식별하고 공백이나 주석을 제거하여 구문 분석기에 입력 가능한 형태로 정보를 구성한다. - 구문 분석 - 구문 오류
구문 오류는 계산기의 입력된 수식의 구문이 잘못되었음을 의미하며, 괄호 누락, 음수 기호와 빼기 기호의 잘못된 사용 등 다양한 형태로 발생한다. - 패턴 - 줄무늬
줄무늬는 두 가지 이상의 색깔이 반복되는 패턴으로, 의류, 자연, 경고 표지 등 다양한 분야에서 활용되며 시각적 효과와 위장 효과를 가진다. - 패턴 - 계층
계층은 객체들을 순위나 중요도에 따라 배열한 구조를 의미하며, 피라미드, 트리 구조 등으로 표현되고 조직, 생물학 등 다양한 분야에서 활용되지만, 인식론적, 사회적 비판도 존재한다.
패턴 매칭 | |
---|---|
지도 정보 | |
개요 | |
정의 | 주어진 토큰 시퀀스에서 특정 패턴의 구성 요소를 확인하는 행위 |
관련 분야 | 함수형 프로그래밍 |
혼동 주의 | 문자열 매칭, 패턴 인식 |
함수형 프로그래밍에서의 패턴 매칭 | |
특징 | 데이터 구조를 분해하고 각 부분에 변수를 바인딩하는 데 사용 함수의 인수를 기반으로 여러 함수 정의를 제공하는 방법으로 사용 람다 대수에서 영감을 받음 |
장점 | 코드의 간결성과 명확성을 높임 복잡한 조건부 로직을 단순화 |
주요 언어 지원 | 하스켈 ML 계열 언어 (OCaml, Standard ML, F#) 스칼라 클로저 엘릭서 러스트 스위프트 파이썬 (3.10 버전 이후) 루비 (3.0 버전 이후) C 샤프 (7.0 버전 이후) |
사용 예시 | 값 매칭: 특정 값과 일치하는지 확인 타입 매칭: 특정 타입인지 확인 구조 매칭: 복잡한 데이터 구조의 특정 형태와 일치하는지 확인 시퀀스 매칭: 리스트나 튜플 등의 요소 매칭 |
추가 특징 | 와일드카드 패턴 ( _ ): 특정 값을 무시하고 매칭 가드 조건: 추가적인 조건 충족 여부 확인 변수 바인딩: 매칭된 값을 변수에 할당 |
기타 | |
관련 개념 | 정규 표현식 패턴 인식 |
사용 예시 | 컴파일러의 렉싱 및 파싱 과정 텍스트 에디터에서의 검색 및 치환 데이터베이스 질의어 처리 인공지능 분야의 패턴 인식 |
2. 역사
패턴 매칭은 1957년 COMIT을 시작으로, SNOBOL(1962), Refal(1968), Prolog(1972), SASL(1976), NPL(1977), 켄트 재귀 계산기(KRC)(1981) 등 초기 프로그래밍 언어에서 그 구조를 찾아볼 수 있다.
ML(1973)과 Standard ML(1983)은 함수 인수 패턴 매칭을 제공했고, 이는 Haskell(1990), Scala(2004), F#(2005) 등 함수형 프로그래밍 언어에 영향을 주었다. Caml(1985)의 `match` 키워드 패턴 매칭은 OCaml(1996), F#(2005), F*(2011), Rust(2015) 등에서 계승되었다.
QED 편집기와 TECO 같은 텍스트 편집기와 수식 처리 시스템도 패턴 매칭을 지원한다.[14]
2. 1. 초기 프로그래밍 언어
패턴 매칭 구조를 가진 초기 프로그래밍 언어로는 COMIT(1957), SNOBOL(1962), 트리 기반 패턴 매칭을 지원하는 Refal(1968), Prolog(1972), SASL(1976), NPL(1977), KRC(1981)가 있다.[9]많은 텍스트 편집기들이 다양한 종류의 패턴 매칭을 지원한다. QED 편집기는 정규 표현식 검색을 지원하며, 일부 버전의 TECO는 검색에서 OR 연산자를 지원한다.[14]
2. 2. 함수형 프로그래밍 언어의 발전
COMIT(1957), SNOBOL(1962), 트리 기반 패턴 매칭을 지원하는 Refal(1968), Prolog(1972), SASL(1976), NPL(1977), 켄트 재귀 계산기(KRC)(1981)는 패턴 매칭 구조를 가진 초기 프로그래밍 언어이다.ML 프로그래밍 언어(1973)와 그 방언인 Standard ML(1983)의 함수 인수 패턴 매칭 기능은 Haskell(1990), Scala(2004), F#(2005) 등 함수형 프로그래밍 언어들에 영향을 주었다. ML 방언인 Caml(1985)에 도입된 `match` 키워드를 사용한 패턴 매칭 구문은 OCaml(1996), F#(2005), F*(2011), Rust(2015)와 같은 프로그래밍 언어에서 계승되었다.
2. 3. 텍스트 편집기와 수식 처리 시스템
많은 텍스트 편집기들이 다양한 종류의 패턴 매칭을 지원한다. QED 편집기는 정규 표현식 검색을 지원하며, 일부 버전의 TECO는 검색에서 OR 연산자를 지원한다.[14]수식 처리 시스템은 일반적으로 대수식의 패턴 매칭을 지원한다.[14]
3. 기본 패턴
패턴 매칭에서 가장 간단한 패턴은 명시적인 값 또는 변수이다. 예를 들어, 하스켈 구문으로 작성된 간단한 함수 정의를 살펴보자. (함수 매개변수는 괄호로 묶지 않고 공백으로 구분하며, `=`는 할당이 아니라 정의이다.)
```haskell
f 0 = 1
```
위 코드에서 `0`은 단일 값 패턴이다. `f`에 인수 `0`이 주어지면 패턴이 일치하고 함수는 `1`을 반환한다. 다른 인수가 있으면 일치하지 않으므로 함수가 실패한다. 구문은 함수 정의에서 대체 패턴을 지원하므로, 더 일반적인 인수를 사용하도록 정의를 확장할 수 있다.
```haskell
f n = n * f (n-1)
```
여기서 첫 번째 `n`은 단일 변수 패턴으로, 모든 인수와 일치하며 이름 `n`에 바인딩되어 정의의 나머지 부분에서 사용된다. 하스켈(최소한 Hope와는 달리)에서는 패턴이 순서대로 시도되므로 입력이 `0`인 경우 첫 번째 정의가 여전히 적용되지만, 다른 인수의 경우 함수는 인수인 `n`을 사용하여 `n * f (n-1)`을 반환한다.
와일드카드 패턴(종종 `_`로 작성)도 간단하다. 변수 이름과 마찬가지로 모든 값과 일치하지만 값을 어떤 이름에도 바인딩하지 않는다. 간단한 문자열 일치 상황에서 와일드카드 일치를 위한 알고리즘은 여러 재귀적 및 비재귀적 변형으로 개발되었다.[10]
4. 트리 패턴
이전 절의 기본 패턴을 사용하여 더 복잡한 패턴을 구성할 수 있다. 이는 일반적으로 다른 값을 결합하여 값을 만드는 방식과 동일하다. 변수 및 와일드카드 부분을 사용하는 패턴은 단일 값으로 구성되지 않고, 구체적인 요소와 패턴 구조 내에서 변할 수 있는 요소의 조합인 값 그룹과 일치한다는 차이점이 있다.
트리 패턴은 노드에서 시작하여 일부 분기와 노드를 지정하고, 변수 또는 와일드카드 패턴을 사용하여 일부를 지정하지 않고 트리의 일부를 설명한다. 추상 구문 트리와 대수적 자료형을 생각하면 이해하기 쉽다.
Haskell에서 다음 줄은 정수와 문자열을 래핑하는 단일 데이터 생성자 `ColorConstructor`를 갖는 대수적 자료형 `Color`를 정의한다.
```haskell
data Color = ColorConstructor Integer String
```
생성자는 트리의 노드이며 정수와 문자열은 분기의 리프이다.
`Color`를 추상 자료형으로 만들기 위해 함수를 작성하려면, 자료형과 상호 작용하는 함수를 작성해야 한다. 따라서 자료형에서 일부 데이터(예: 문자열 부분 또는 정수 부분만)를 추출해야 한다.
`Color`형 변수를 전달하는 경우, 이 변수에서 데이터를 가져오기 위해 간단한 트리 패턴을 사용할 수 있다. 예를 들어, `Color`의 정수 부분을 가져오는 함수는 다음과 같이 작성할 수 있다.
```haskell
integerPart (ColorConstructor theInteger _) = theInteger
```
마찬가지로, 문자열 부분을 가져오는 함수는 다음과 같다.
```haskell
stringPart (ColorConstructor _ theString) = theString
```
Haskell의 데이터 레코드 구문을 사용하여 이러한 함수의 생성을 자동화할 수 있다.
OCaml 예제는 재귀적 자료형에 의해 생성된 더 복잡한 구조와 일치하는 방법을 보여준다. 이 예제는 요소 삽입 후 다시 균형을 맞추는 함수와 함께 적흑 트리를 정의한다. 컴파일러는 컴파일 시점에 케이스 목록이 완전하고 중복이 없음을 확인한다.
```ocaml
type color = Red | Black
type 'a tree = Empty | Tree of color * 'a tree * 'a * 'a tree
let rebalance t = match t with
| Tree (Black, Tree (Red, Tree (Red, a, x, b), y, c), z, d)
| Tree (Black, Tree (Red, a, x, Tree (Red, b, y, c)), z, d)
| Tree (Black, a, x, Tree (Red, Tree (Red, b, y, c), z, d))
| Tree (Black, a, x, Tree (Red, b, y, Tree (Red, c, z, d)))
- > Tree (Red, Tree (Black, a, x, b), y, Tree (Black, c, z, d))
| _ -> t (* 이전 패턴과 일치하지 않는 경우 '포괄적' 케이스 *)
5. 패턴을 이용한 데이터 필터링
패턴 매칭은 특정 구조의 데이터를 필터링하는 데 사용할 수 있다. 예를 들어, 하스켈에서는 리스트 내포를 이러한 종류의 필터링에 사용할 수 있다.
```haskell
[A x | A x <- [A 1, B 1, A 2, B 2]]
```
위 코드는 다음과 같이 평가된다.
```text
[A 1, A 2]
6. Mathematica에서의 패턴 매칭
Mathematica에서 패턴은 트리의 위치에 `_`를 넣는 것을 포함한다. 예를 들어, 패턴 `A[_]`는 `A[1]`, `A[2]`, 또는 더 일반적으로 `A[''x'']` (여기서 ''x''는 임의의 엔티티)와 같은 요소와 일치한다. 이 경우 `A`는 구체적인 요소이고, `_`는 변할 수 있는 트리의 부분을 나타낸다. `_` 앞에 붙는 심볼은 일치하는 내용을 해당 변수 이름에 바인딩하고, `_` 뒤에 붙는 심볼은 해당 심볼의 노드로 일치를 제한한다. 빈칸 자체도 내부적으로 `_`에 대해 `Blank[]`, `_x`에 대해 `Blank[x]`로 표현된다.[11]
Mathematica 함수 `Cases`는 첫 번째 인수의 요소 중 두 번째 인수의 패턴과 일치하는 요소를 필터링한다.[11] 예를 들어, `Cases[{a[1], b[1], a[2], b[2]}, a[_] ]`는 `{a[1], a[2]}`로 평가된다. 패턴 매칭은 표현식의 ''구조''에 적용된다. 다음 예에서 `Cases[ {a[b], a[b, c], a[b[c], d], a[b[c], d[e]], a[b[c], d, e]}, a[b[_], _] ]`는 `a[b[_],_]`과 일치하는 요소만 있기 때문에 `{a[b[c],d], a[b[c],d[e]]}`를 반환한다.
Mathematica에서는 계산 과정에서 생성되는 구조를 생성 방법이나 위치에 관계없이 추출할 수도 있다. `Trace` 함수를 사용하여 계산을 모니터링하고 패턴과 일치하는 요소를 반환할 수 있다. 예를 들어, 피보나치 수를 다음과 같이 정의할 수 있다.
```mathematica
fib[0|1]:=1
fib[n_]:= fib[n-1] + fib[n-2]
```
그런 다음 `fib[3]`이 주어졌을 때 재귀적 피보나치 호출의 순서를 `Trace[fib[3], fib[_]]`를 통해 확인할 수 있다. 이는 계산 구조에서 패턴 `fib[_]`의 발생을 나타내는 구조인 `{fib[3],{fib[2],{fib[1]},{fib[0]}},{fib[1]}}`를 반환한다.
기호 프로그래밍 언어에서는 패턴을 함수의 인수 또는 데이터 구조의 요소로 쉽게 사용할 수 있다. 이로 인해 패턴을 사용하여 데이터 조각에 대해 선언적으로 진술하고 함수가 작동하는 방식을 유연하게 지시할 수 있다.
예를 들어, Mathematica 함수인 `Compile`을 사용하면 코드의 효율성을 높일 수 있다. 부분식 ``은 `Compile`에게 컴파일 목적으로 `com[_]` 형식의 식을 정수로 간주할 수 있다는 것을 지시한다.
```mathematica
com[i_] := Binomial[2i, i]
Compile[{x, {i, _Integer}}, x^com[i], ]
7. 패턴 매칭과 문자열
패턴 매칭의 가장 일반적인 형태는 문자열을 이용하는 것이다. 많은 프로그래밍 언어에서 특정 문자열 구문을 사용하여 정규 표현식을 나타내는데, 이는 문자열 문자를 설명하는 패턴이다.[14]
패턴 매칭 구조를 갖춘 초기 프로그래밍 언어로는 COMIT(1957), SNOBOL(1962), Refal(1968), 트리 기반 패턴 매칭을 지원하는 Prolog(1972), SASL(1976), NPL(1977), KRC(1981) 등이 있다.
QED 편집기와 같은 많은 텍스트 편집기들이 다양한 종류의 패턴 매칭을 지원한다. QED 편집기는 정규 표현식 검색을 지원하며, 일부 버전의 TECO는 검색에서 OR 연산자를 지원한다.[14]
수식 처리 시스템은 일반적으로 대수식의 패턴 매칭을 지원한다.[14]
7. 1. 문자열을 위한 트리 패턴
Mathematica에서는 문자열이 `StringExpression` 루트와 모든 문자를 순서대로 루트의 자식으로 가지는 트리로 표현된다. 따라서 "임의의 양의 후행 문자"와 일치시키려면, 단일 문자와만 일치하는 `_`와 달리 새로운 와일드카드 `___`가 필요하다.[1]Haskell과 일반적인 함수형 프로그래밍 언어에서는 문자열이 문자의 함수형 리스트로 표현된다. 함수형 리스트는 빈 리스트이거나 기존 리스트에 생성된 요소로 정의된다. Haskell 구문은 다음과 같다.[1]
```haskell
[] -- 빈 리스트
x:xs -- 리스트 xs에 생성된 요소 x
```
일부 요소가 있는 리스트의 구조는 따라서 `요소:리스트`이다. 패턴 매칭에서는 특정 데이터가 특정 패턴과 같다고 주장한다. 예를 들어, 다음 함수에서:[1]
```haskell
head (element:list) = element
```
`head` 인수의 첫 번째 요소를 `element`라고 주장하고, 함수는 이를 반환한다. 리스트의 정의 방식, 즉 리스트에 생성된 단일 요소 때문에 이것이 첫 번째 요소라는 것을 알 수 있다. 빈 리스트는 빈 리스트에는 헤드(생성된 첫 번째 요소)가 없으므로 패턴과 전혀 일치하지 않는다.[1]
예에서 `list`는 사용하지 않으므로 무시할 수 있으며, 따라서 함수를 다음과 같이 작성할 수 있다.[1]
```haskell
head (element:_) = element
```
이에 해당하는 Mathematica 변환은 다음과 같이 표현된다.[1]
```mathematica
head[element, ]:=element
```
Mathematica에서 예를 들어,[1]
```mathematica
StringExpression["a",_]
```
는 두 글자로 시작하는 문자열 중 "a"로 시작하는 문자열과 일치한다.
Haskell에서 같은 패턴은 다음과 같다.[1]
```haskell
['a', _]
```
문자열의 여러 가지 관련 특징을 나타내는 기호적 요소를 도입할 수 있다. 예를 들어,[1]
```mathematica
StringExpression[LetterCharacter, DigitCharacter]
```
는 처음에 문자, 그다음에 숫자로 구성된 문자열과 일치한다.
Haskell에서는 가드를 사용하여 동일한 일치를 달성할 수 있다.[1]
```haskell
[letter, digit] | isAlpha letter && isDigit digit
```
기호적 문자열 조작의 주요 장점은 별도의 특수 목적 하위 단위가 아니라 프로그래밍 언어의 나머지 부분과 완전히 통합될 수 있다는 것이다. 언어의 모든 기능을 활용하여 패턴 자체를 구축하거나 패턴을 포함하는 프로그램을 분석하고 변환할 수 있다.[1]
7. 2. SNOBOL
SNOBOL(''StriNg Oriented and symBOlic Language'')은 1962년부터 1967년까지 AT&T 벨 연구소에서 데이비드 J. 파버, 랄프 E. 그리스월드, 아이반 P. 폴론스키가 개발한 컴퓨터 프로그래밍 언어이다.SNOBOL4는 패턴을 일급 데이터 형식(프로그래밍 언어에서 다른 어떤 데이터 형식에도 허용되는 모든 방식으로 조작할 수 있는 데이터 형식)으로 사용하고 패턴 연결 및 선택 연산자를 제공한다는 점에서 대부분의 프로그래밍 언어와 다르다. 실행 중에 생성된 문자열은 프로그램으로 취급되어 실행될 수 있다.
SNOBOL은 1960년대 후반과 1970년대 초 미국 대학에서 널리 교육되었으며, 1970년대와 1980년대에는 인문학 분야에서 텍스트 조작 언어로 널리 사용되었다.
SNOBOL의 등장 이후 awk와 펄과 같은 새로운 언어들이 정규 표현식을 이용한 문자열 조작을 유행시켰다. 그러나 SNOBOL4 패턴은 BNF 문법을 포함하며, 이는 맥락 자유 문법과 동등하고 정규 표현식보다 강력하다.[12]
참조
[1]
웹사이트
Pattern Matching - C# Guide
https://docs.microso[...]
2024-03-13
[2]
웹사이트
Pattern Matching - F# Guide
https://docs.microso[...]
2021-11-05
[3]
웹사이트
A Gentle Introduction to Haskell: Patterns
http://www.haskell.o[...]
[4]
웹사이트
What's New In Python 3.10 — Python 3.10.0b3 documentation
https://docs.python.[...]
2021-07-06
[5]
웹사이트
pattern_matching - Documentation for Ruby 3.0.0
https://docs.ruby-la[...]
2021-07-06
[6]
웹사이트
Pattern Syntax - The Rust Programming Language
https://doc.rust-lan[...]
[7]
웹사이트
Pattern Matching
https://docs.scala-l[...]
2021-01-17
[8]
웹사이트
Patterns — The Swift Programming Language (Swift 5.1)
https://docs.swift.o[...]
[9]
논문
Symbolic Integration
MIT Project MAC
1967-12
[10]
웹사이트
Wildcard matching algorithms
http://xoomer.virgil[...]
2003
[11]
웹사이트
Cases—Wolfram Language Documentation
https://reference.wo[...]
2020-11-17
[12]
간행물
A theory of discrete patterns and their implementation in SNOBOL4
Commun. ACM
1973-02
[13]
웹사이트
https://wiki.haskell[...]
[14]
논문
Symbolic Integration
MIT Project MAC
1967-12
관련 사건 타임라인
( 최근 20개의 뉴스만 표기 됩니다. )
스칼라의 미래, 자바와 코틀린 사이에서 – 바이라인네트워크
오라클, 자바24 출시 – 바이라인네트워크
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com