Reason
  • 문서
  • 해보기
  • API
  • 커뮤니티
  • 블로그
  • Languages icon한국어
    • 日本語
    • English
    • Deutsch
    • Español
    • Français
    • Português (Brasil)
    • Русский
    • Українська
    • 中文
    • 繁體中文
    • 번역 돕기
  • GitHub

›언어 기본

소개

  • What & Why

Setup

  • 설치
  • 에디터 플러그인

언어 기본

  • 개요
  • Let 바인딩
  • 원시 타입
  • 기본 자료구조
  • 타입
  • 레코드
  • Variant
  • Options and nullability
  • 함수
  • 재귀
  • 비구조화
  • 패턴 매칭
  • Mutable Bindings
  • 반복문
  • Modules

Advanced Features

  • JSX
  • 외부 접근
  • 예외
  • 오브젝트

JavaScript

  • 연동
  • 문법 치트시트
  • Pipe First
  • 프라미스
  • 라이브러리
  • JS에서 변환

추가 사항

  • 자주 물어보는 질문
  • 추가적으로 매력적인 것들
Translate

타입

타입은 값이 어떤 종류인지를 나타냅니다. 이 값이 문자열일까요, 정수일까요, 아니면 어떤 복잡한 구조체일까요? 값의 타입이 바로 그 답을 알려 줍니다. 엄격한 타입 시스템은 컴파일 도중에 큰 부류의 버그를 없애고, 다른 많은 버그를 잡아 주는 강력한 도구입니다.

Reason에선 거의 대부분의 타입이 추론될 수 있습니다. 컴파일러는 프로그램 속 모든 것의 타입을 추론하고, 추론한 타입이 말이 되도록 보장할 것입니다. 따라서 우리는 모든 값의 타입을 쓰지 않고도 엄격한 타입 시스템의 이점을 누릴 수 있습니다.

기초

여기 [let binding](let binding.md)이 하나 있습니다. 이름은 count이고, 타입은 int, 값은 42입니다. 우리는 명시적으로 그게 int라고 쓰지 않았지만, 타입은 추론됩니다.

여러분이 타입을 쓰지 않아도 Reason의 모든 것에는 타입이 있습니다.

let count = 42;

타입은 주석을 통해 명시적으로 추가될 수 있습니다.

let count: int = 42;

count가 타입을 가지기 때문에 컴파일러는 우리가 이 값을 가지고 무엇을 할 수 있고 없는지를 알고 있습니다.

/* 덧셈은 허용됨 */
let nextCount = count + 1;

/* 오류: count는 list가 아님 */
let x = List.map(fn, count);

주석 (Annotation)

타입 주석은 거의 모든 곳에 사용할 수 있습니다. Reason의 타입 추론 때문에 자주 필요하지는 않지만, 여러분의 프로그램의 타입에 대한 이해를 더 확실히 갖게 하는 데에 도움이 될 수 있습니다.

아래 예시 곳곳에 int와 string이 사용되었습니다.

let five: int = 5;
let nine = (five: int) + (4: int);
let add = (x: int, y: int): int => x + y;
let drawCircle = (~radius: int): string => "hi";

별칭 (Alias)

타입에 대해 별칭을 정의할 수 있습니다. 이는 간단한 타입에 의미를 붙일 때와 쓰기엔 너무 길어지는 복잡한 타입을 다룰 때 도움이 됩니다.

type seconds = int;
type timeInterval = (seconds, seconds);

별칭 seconds를 사용하여 sleep 함수가 어떻게 동작하는지가 분명해졌습니다. int를 사용했다면 그렇지 않았을 것입니다.

let sleep = (time: seconds) => { ... }

타입 별칭은 variants나 records를 다루는 등 몇몇 경우에 필요합니다.

타입 파라미터

타입은 다른 언어의 제네릭과 비슷하게, 타입 파라미터를 받을 수 있습니다. 파라미터화된 타입은 여러 타입의 값을 다루는 구조를 정의할 때 유용합니다. 인자로 int, float, string을 받는 list 타입 하나를 쓰는 게 세 타입 intList, floatList, stringList을 쓰는 것보다 낫습니다.

타입을 정의할 때 파라미터 앞에는 작은따옴표(') 하나를 붙입니다.

type list('item) = ...

이 타입을 주석으로써 사용할 때 파라미터 자리에는 구체적인 타입이 채워집니다.

let x: list(int) = [1, 2, 3];
let y: list(string) = ["one", "two", "three"];

타입은 파라미터 여러 개를 가질 수 있고, 중첩될 수도 있습니다.

type pair('a, 'b) = ('a, 'b);

let x: pair(int, string) = (1, "one");
let y: pair(string, list(int)) = ("123", [1, 2, 3]);
  • 타입 파라미터 이름을 'a, 'b, 'c, ... 로 짓는 것이 일반적인 컨벤션입니다.
  • 타입 파라미터도 추론될 수 있습니다!

불투명 타입

불투명 타입은 유저들에게 노출되는 구현 세부 사항을 제한하는 강력한 도구입니다. 불투명 타입을 사용하면 변경 요구 사항을 맞추도록 더 쉽고 안전하게 구현을 수정할 수 있습니다.

알아두기: 이 예시들에서는 간단함을 위해 모듈 타입을 사용했습니다. 하지만 보통 불투명 타입은 인터페이스 파일을 써서 만듭니다.

준비

Duration.t는 불투명 타입입니다. 구체적 타입은 숨겨져 있고, 제한된 종류의 함수만을 사용해서 상호작용할 수 있습니다.

(type t;라고 쓰는 것은 t를 불투명하게 만듭니다. type t = int;라고 쓰면 t는 불투명하지 않고 구체적인 타입을 가질 것입니다.)

module type Duration = {
  /* 불투명 타입 */
  type t;
  let fromSeconds: int => t;
  let add: (t, t) => t;
};

module Duration: Duration = {
  /* Duration이 몇 초인지 */
  type t = int;
  let fromSeconds = value => value;
  let add = (x, y) => x + y;
};

Duration 모듈을 써서 불투명 타입을 만들고 사용합니다.

let oneMinute = Duration.fromSeconds(60);
let twoMinutes = Duration.add(oneMinute, oneMinute);

보통의 정수 함수는 Duration.t 타입 값을 받으면 일부러 오류를 냅니다.

/* 오류: int를 예상했지만 Duration.t를 받음 */
let twoMinutes = oneMinute + oneMinute;

구현 바꾸기

만약 우리가 duration의 정밀도를 높여서 밀리초 단위의 정밀도를 허용하고 싶다면 자신있게 구현을 바꿔도 아무것도 망가뜨리지 않는다고 확신할 수 있습니다.

module type Duration = {
  type t;
  let fromSeconds: int => t;
  let fromMS: int => t;
  let add: (t, t) => t;
};

module Duration: Duration = {
  /* Duration in milliseconds */
  type t = int;
  let fromSeconds = value => value * 1000;
  let fromMS = value => value;
  let add = (x, y) => x + y;
};

아래 코드는 위에서 했던 것과 완전히 똑같이 동작합니다.

let oneMinute = Duration.fromSeconds(60);
let twoMinutes = Duration.add(oneMinute, oneMinute);

하지만 이제는 1초 미만의 duration도 지원할 수 있습니다.

let halfSecond = Duration.fromMS(500);
let longerThanOneMinute = Duration.add(oneMinute, halfSecond);

이는 코드를 더 쉽게 코드를 관리하고, 더 안전하게 변경하는 데 도움이 되는 기법입니다.

← 기본 자료구조레코드 →
  • 기초
  • 주석 (Annotation)
  • 별칭 (Alias)
  • 타입 파라미터
  • 불투명 타입
    • 준비
    • 구현 바꾸기