언어 기초

타입

추론과 타입 표기를 이해하고, 필요한 경계에 맞춰 유니온·함수 타입·명목 데이터를 선택합니다.

타입은 프로그램을 실행하기 전에 “이 경계에는 어떤 값이 들어올 수 있는가?”를 검사하게 해 줍니다. 초기값만 봐도 타입이 분명한 지역 값에는 대개 타입을 적지 않아도 됩니다. 입력과 결과, 도메인의 중요한 선택을 드러내고 싶을 때 타입을 명시하세요.

하나의 프로그램에서 시작하기

다음 코드를 types.tpz로 저장합니다.

TOPAZ
type Stage = "draft" | "ready"

function describe(stage: Stage, checks: int) -> string {
    "{stage} after {checks} checks"
}

let checks = 3
let current: Stage = "ready"
let render: (Stage, int) -> string = describe

print(render(current, checks))

먼저 타입 경계를 검사한 뒤 실행합니다.

BASH
topaz check types.tpz
topaz run types.tpz

결과는 다음과 같습니다.

출력
ready after 3 checks

결과에서 타입 읽어 내기

checks에는 타입 표기가 없습니다. 초기값이 정수이므로 토파즈가 int로 추론합니다. 반면 current에는 타입을 적었습니다. 이 프로그램이 임의의 string이 아니라 Stage만 받겠다는 의도를 나타냅니다.

Stage"draft" | "ready"라는 리터럴 유니온에 붙인 투명한 별칭입니다. 두 값 가운데 하나만 허용하고 다른 문자열은 거부합니다. 별칭은 선택에 이해하기 쉬운 이름을 붙이지만, 별도의 런타임 정체성을 만들지는 않습니다.

render에는 함수 타입이 쓰였습니다. (Stage, int) -> string은 “Stageint를 받아 string을 돌려주는 함수”라는 뜻입니다. 이름 있는 함수 describe가 바로 이 형태이므로 바인딩에 저장한 뒤 호출할 수 있습니다.

기본 타입 이름은 소문자로 씁니다. int, float, bool, string, 그리고 유닛 타입 ()가 있습니다. 자주 쓰는 컨테이너는 Array<T>, Map<K, V>, Set<T>처럼 이름 있는 생성자로 표현합니다. 예상 가능한 값의 부재에는 Option<T>, 복구 가능한 실패에는 Result<T, E>를 사용합니다.

의도에 맞는 형태 고르기

필요한 것권장 형태이유
타입이 분명한 지역 값타입 추론초기값만으로도 타입이 잘 드러납니다.
공개 입력·결과 또는 중요한 지역 경계타입 표기검사기와 독자가 의도한 계약을 바로 알 수 있습니다.
정해진 여러 대안 가운데 하나유니온 또는 리터럴 유니온 별칭허용되는 대안이 코드에 그대로 나타납니다.
나중에 호출할 수 있는 값(int) -> bool 같은 함수 타입매개변수와 결과 타입이 함수 값과 함께 유지됩니다.
도메인 정체성, 필드, 이름 붙은 경우record, enum, newtype내부 모양이 비슷해도 서로 다른 타입으로 남습니다.

type 별칭은 표현을 읽기 쉽게 만들지만 원래 타입과 구분되는 정체성은 만들지 않습니다. 모양이 비슷한 두 값을 섞는 것이 실제 오류라면 명목 데이터를 선택하세요. 레코드와 명목 데이터에서 record, enum, newtype의 생성과 패턴을 비교할 수 있습니다.

빈 값에는 문맥 제공하기

어떤 값은 그 자체만으로 타입을 모두 알려 주지 못합니다. 빈 배열에는 원소 타입이 없고, None만으로는 어떤 타입의 값이 없는지 알 수 없습니다. 타입 표기, 함수 매개변수, 선언된 결과 타입처럼 주변 문맥을 제공하세요.

let names: Array<string> = []
let selected: Option<int> = None

여기서는 올바른 형태를 설명하기 위해 텍스트로 표시했습니다. 이 페이지에서 실제로 검증하는 프로그램은 위의 실행 예제입니다.

흔한 실수: 대상 언어의 타입 표기 가져오기

토파즈 컬렉션 타입은 Array<T>, Map<K, V>, Set<T>로 씁니다. 함수 타입은 매개변수 타입을 괄호로 묶고 -> 뒤에 결과 타입을 적습니다. 이 표기를 일정하게 사용해야 검사기와 생성 대상이 같은 소스 계약을 공유합니다.

정확한 한계

  • intfloat 사이에는 암묵적 변환이 없습니다.
  • 제네릭 타입 매개변수는 불변입니다. 내용이 비슷하다는 이유만으로 서로 다른 타입 인수가 호환되지는 않습니다.
  • 제네릭 제약은 이름 있는 함수의 타입 매개변수에만 붙일 수 있습니다. 허용되는 1계층 형태는 함수와 제네릭에서 설명합니다.
  • 재귀 타입 별칭, 분산(variance) 표기, 고위 다형성, 더 넓은 리플렉션은 아직 지원하지 않습니다.
  • 문맥을 제공한 뒤에도 타입 매개변수가 결정되지 않는 빈 제네릭 값은 실행 중에 추측하지 않고 정적 오류로 거부합니다.

타입 추론, 타입 표기, 가변성이 아직 낯설다면 값과 함수를 다시 살펴보세요. 값의 부재와 실패를 구분하려면 Null·Option·Result·실행 오류로 이어가면 됩니다.