데이터 구조 계약
데이터 구조 계약
데이터 구조 계약은 리스트, 페어, 벡터, 박스, 해시 테이블, 딕셔너리 같은 데이터 구조를 검사하기 위한 계약들이에요. 이런 계약들은 요소에 대한 하위 계약을 조합해 복합 구조를 계약으로 감싸요.
이 절에서는 Racket이 제공하는 주요 데이터 구조 계약 결합자들을 다뤄요.
출처: Racket Reference
본문
데이터 구조 계약은 값을 그 요소 단위로 검사해요. 예를 들어 (listof integer?)는 정수들의 리스트를 나타내는 계약이에요.
계약 list/c, list*, cons/c는 racket/contract/base가 제공해요. 이 절의 다른 모든 계약들은 racket/contract가 제공하지만 racket/contract/base는 제공하지 않아요.
이 절에서 다루는 데이터 구조 계약들:
list/c list* cons/c cons* and/c or/c not/c
between/c one-of/c vectorof vector/c boxof box/c
hash/c alistof plistof dictionary/c set/c sequence/c
listof proper-listof
procedure
(listof c) → (and/c pair? (listof c)) | null?
c: contract?
c를 만족하는 원소들로 이루어진 (가변) 리스트를 나타내는 계약이에요. (listof c)는 c를 만족하는 원소들의 임의 길이 리스트를 검사해요. 리스트의 각 원소에 c가 적용돼요.
syntax list/c
(list/c c ...)
c : contract?
원소의 수와 순서가 정확히 일치하는 고정 길이 리스트를 나타내는 계약이에요. (list/c c1 c2)는 정확히 두 원소를 갖고, 첫 번째가 c1, 두 번째가 c2를 만족하는 리스트를 검사해요.
syntax list*
(list* c ...)
c : contract?
마지막 원소가 리스트인 (가변) 리스트를 나타내는 계약이에요. (list* c1 c2)는 첫 원소가 c1이고 나머지가 (listof c2)인 리스트를 검사해요. 즉 (cons/c c1 (listof c2))와 같아요.
syntax cons/c
(cons/c c1 c2)
c1 : contract?,c2 : contract?
c1을 만족하는 car와 c2를 만족하는 cdr을 가진 페어를 나타내는 계약이에요.
syntax cons*
(cons* c1 c2 ...)
c1 c2 ... : contract?
(cons/c c1 (cons/c c2 ...))처럼 중첩 페어를 나타내는 계약이에요. 마지막 c는 페어의 cdr에 대한 계약이에요.
syntax pair/c
(pair/c c1 c2)
(cons/c c1 c2)와 같은 계약이에요. 페어를 나타내는 계약으로, cons/c의 별칭이에요.
procedure
(proper-listof c) → contract?
c : contract?
적절한(proper) 리스트, 즉 마지막이 null인 리스트를 나타내는 계약이에요. listof와 달리 순환(circular) 또는 부적절(improper) 리스트를 거부해요.
procedure
(and/c c ...) → contract?
c : contract?
모든 c들을 모두 만족하는 값의 계약이에요. c들 중 어느 하나라도 실패하면 계약이 실패해요.
procedure
(or/c c ...) → contract?
c : contract?
c들 중 적어도 하나를 만족하는 값의 계약이에요. c들 중 어떤 것도 만족하지 않으면 계약이 실패해요.
procedure
(not/c c) → contract?
c : contract?
c를 만족하지 않는 값의 계약이에요.
procedure
(between/c lo hi) → contract?
lo : number?,hi : number?
lo 이상 hi 이하인 수의 계약이에요.
procedure
(one-of/c v ...) → contract?
v : any/c
v들 중 하나와 equal?로 같은 값의 계약이에요.
procedure
(vectorof c) → contract?
c : contract?
c를 만족하는 원소들로 이루어진 벡터를 나타내는 계약이에요.
syntax vector/c
(vector/c c ...)
c : contract?
고정 길이 벡터를 나타내는 계약이에요. (vector/c c1 c2)는 정확히 두 원소를 갖고, 각각 c1, c2를 만족하는 벡터를 검사해요.
procedure
(boxof c) → contract?
c : contract?
c를 만족하는 값을 담은 박스를 나타내는 계약이에요.
syntax box/c
(box/c c)
c : contract?
c를 만족하는 값을 담은 박스를 나타내는 계약이에요. boxof와 유사하며, 특정 계약 맥락에서 구별돼요.
procedure
(hash/c key-c val-c ...) → contract?
(hash/c (key-c val-c) ...) → contract?
key-c : contract?,val-c : contract?
키가 key-c, 값이 val-c를 만족하는 해시 테이블을 나타내는 계약이에요. (정확히 두 인자를 주는) 첫 형태는 모든 키·값 쌍을 검사하고, 쌍들의 리스트를 주는 두 번째 형태는 각 쌍의 유형별 배정을 지원해요.
procedure
(alistof c d) → contract?
(alistof c) → contract?
c : contract?,d : contract?
연관 리스트(association list)를 나타내는 계약이에요. 각 요소가 c를 만족하는 키와 d를 만족하는 값으로 이루어진 페어인 리스트를 검사해요. d가 생략되면 쌍의 car만 c로 검사돼요.
procedure
(plistof c) → contract?
c : contract?
각 요소가 c를 만족하는 프로퍼티 리스트(property list)를 나타내는 계약이에요. 프로퍼티 리스트는 키-값 쌍이 교대로 나열된 평평한(flat) 리스트예요.
procedure
(dictionary/c key-c val-c) → contract?
key-c : contract?,val-c : contract?
키가 key-c, 값이 val-c를 만족하는 딕셔너리(예: 해시 테이블)를 나타내는 계약이에요.
procedure
(set/c c) → contract?
c : contract?
모든 원소가 c를 만족하는 집합을 나타내는 계약이에요.
syntax sequence/c
(sequence/c c)
c : contract?
원소들이 c를 만족하는 시퀀스를 나타내는 계약이에요. 리스트, 벡터, 문자열 등 시퀀스로 쓰이는 모든 값에 적용돼요.
syntax stream/c
(stream/c c)
c : contract?
원소들이 c를 만족하는 스트림을 나타내는 계약이에요.
데이터 구조 계약은 중첩이 가능해요. 예를 들어 (listof (list/c integer? string?))는 각 원소가 정수와 문자열의 페어인 리스트를 나타내는 계약이에요. 이렇게 결합하는 방식 덕분에 복잡한 데이터 구조도 계약으로 명확하게 표현할 수 있어요.