좀 더 깊게 보이면 실제로 기본 언어로 배열을 포함합니다.
- 5 번째 개정 된 계획 보고서 (R5RS)에는 벡터 유형이 포함되어 있으며 , 이는 임의 액세스에 대한 선형 시간보다 나은 고정 크기 정수 색인 모음입니다.
- Haskell 98 보고서는 배열 유형 도 있습니다.
그러나 함수형 프로그래밍 명령은 배열 또는 이중 연결 목록보다 단일 연결 목록을 오랫동안 강조해 왔습니다. 사실, 지나치게 강조했을 가능성이 높습니다. 그러나 몇 가지 이유가 있습니다.
첫 번째는 단일 연결 목록이 가장 단순하면서도 가장 유용한 재귀 데이터 형식 중 하나라는 것입니다. Haskell의 목록 유형에 해당하는 사용자 정의 항목은 다음과 같이 정의 할 수 있습니다.
data List a -- A list with element type `a`...
= Empty -- is either the empty list...
| Cell a (List a) -- or a pair with an `a` and the rest of the list.
리스트가 재귀 데이터 유형이라는 사실은리스트에서 작동하는 함수가 일반적으로 구조적 재귀를 사용한다는 것을 의미합니다 . 하스켈 측면에서 : 당신 패턴 목록 생성자에 일치, 당신은 재귀 서브 파트 목록. 이 두 가지 기본 함수 정의에서 변수 as
를 사용 하여 목록의 꼬리를 참조합니다. 재귀 호출은 목록 아래로 "내림차순"입니다.
map :: (a -> b) -> List a -> List b
map f Empty = Empty
map f (Cell a as) = Cell (f a) (map f as)
filter :: (a -> Bool) -> List a -> List a
filter p Empty = Empty
filter p (Cell a as)
| p a = Cell a (filter p as)
| otherwise = filter p as
이 기술은 함수가 모든 유한리스트에 대해 종료되도록 보장하고 문제를 해결하는 좋은 기술이기도합니다. 문제를 더 간단하고 더 테너 블 한 하위 부분으로 자연스럽게 나누는 경향이 있습니다.
따라서 단일 링크 목록은 아마도 학생들에게 이러한 기술을 소개 할 수있는 최고의 데이터 유형일 것입니다. 이는 함수형 프로그래밍에서 매우 중요합니다.
두 번째 이유는 "단일 연결 목록이 필요한 이유"가 아니라 "이중 연결 목록 또는 배열이 아닌 이유"가되는 이유입니다. 후자의 데이터 유형은 종종 종종 함수 프로그래밍이 가능한 돌연변이 (수정 가능한 변수)를 요구합니다. 멀리 떨어져 있습니다. 그래서 일어날 때 :
- Scheme과 같은 열성적인 언어에서는 돌연변이를 사용하지 않고 이중 연결 목록을 만들 수 없습니다.
- Haskell과 같은 게으른 언어에서는 돌연변이를 사용하지 않고 이중 연결 목록을 만들 수 있습니다. 그러나 그 목록을 기반으로 새 목록을 만들 때마다 원본의 모든 구조가 아니라면 대부분을 복사해야합니다. 단일 링크 목록을 사용하는 경우 "구조 공유"를 사용하는 함수를 작성할 수 있습니다. 새 목록은 적절한 경우 이전 목록의 셀을 재사용 할 수 있습니다.
- 일반적으로 배열을 변경 불가능한 방식으로 사용한 경우 배열을 수정할 때마다 전체 내용을 복사해야했습니다.
vector
그러나 최근의 Haskell 라이브러리 는이 문제를 크게 개선하는 기술을 찾았습니다.
세 번째이자 마지막 이유는 주로 Haskell과 같은 게으른 언어에 적용됩니다. 게으른 단일 연결 목록은 실제로 메모리 내 목록보다 반복자 와 더 유사합니다 . 코드가 목록의 요소를 순차적으로 소비하고 진행하면서 제거하는 경우 객체 코드는 목록을 진행할 때 목록 셀과 해당 내용 만 구체화합니다.
즉, 전체 목록이 한 번에 메모리에 존재할 필요는 없으며 현재 셀만 존재할 수 있습니다. 현재 셀 이전의 셀은 가비지 수집 될 수 있습니다 (이중 연결 목록에서는 불가능). 현재 셀보다 이후의 셀은 도착할 때까지 계산할 필요가 없습니다.
그것보다 훨씬 더 나아갑니다. fusion 이라는 널리 사용되는 Haskell 라이브러리 에는 컴파일러가 목록 처리 코드를 분석하고 순차적으로 생성되고 소비 된 중간 목록을 찾아서 버리는 기술이 있습니다. 이 지식으로 컴파일러는 목록 셀의 메모리 할당을 완전히 제거 할 수 있습니다. 이는 컴파일 후 Haskell 소스 프로그램의 단일 링크 목록이 실제로 데이터 구조 대신 루프 로 바뀔 수 있음을 의미합니다 .
Fusion은 위에서 언급 한 vector
라이브러리가 불변 배열에 대한 효율적인 코드를 생성하는 데 사용 하는 기술이기도합니다 . Haskell의 매우 고유하지 않은 기본 유형 ( 단일 연결 문자 목록과 동일)을 대체하여 빌드 된 매우 인기있는 bytestring
(바이트 배열) 및 text
(유니 코드 문자열) 라이브러리도 String
마찬가지 [Char]
입니다. 따라서 현대 Haskell에는 융합 지원이 가능한 불변 배열 유형이 매우 보편적 인 추세가 있습니다.
리스트 융합은 단일 링크리스트에서 앞으로 나아갈 수는 있지만 결코 뒤로 갈 수 없다는 사실에 의해 촉진됩니다 . 이는 함수형 프로그래밍에서 매우 중요한 주제를 제시합니다. 데이터 형식의 "모양"을 사용하여 계산의 "모양"을 도출합니다. 요소를 순차적으로 처리하려는 경우 단일 연결 목록은 구조적 재귀와 함께 사용할 때 매우 자연스럽게 액세스 패턴을 제공하는 데이터 유형입니다. "분할 및 정복"전략을 사용하여 문제를 공격하려는 경우 트리 데이터 구조가이를 잘 지원하는 경향이 있습니다.
많은 사람들이 조기에 기능 프로그래밍 마차에서 빠져 나와서 단일 링크 목록에 노출되지만 고급 기본 아이디어에는 노출되지 않습니다.