구별된 공용체 타입은 정해진 수의 이름 있는 케이스를 나타내요. 구별된 공용체의 각 값은 이름 있는 케이스 중 정확히 하나에 대응해요. 이런 종류의 데이터 타입을 _합 타입_이라고 해요.
구별된 공용체의 각 케이스는 선택적으로 데이터를 함께 가질 수 있고, 케이스마다 서로 다른 타입의 데이터를 가질 수 있어요. 어떤 케이스에도 데이터가 없다면, 구별된 공용체는 다른 언어에서 흔히 열거형(또는 enum)이라고 부르는 것과 비슷해요.
구별된 공용체는 type 키워드로 정의하며, 필요한 문법이 아주 적어요. 그래서 사용하기 쉽고, 기본 라이브러리를 비롯한 여러 곳에서 구별된 공용체가 쓰이는 모습을 볼 수 있어요.
// Discriminated union without associated data
type Season =
| Spring
| Summer
| Autumn
| Winter
// Discriminated union with associated data
type Number =
| Integer of int
| Float of float
| Invalid
특정 케이스의 값을 만들 때는 그 케이스의 이름을 쓰면 되고, 이름이 유일하지 않다면 전체 이름을 쓰면 돼요. 케이스 이름은 그냥 생성자 함수이기 때문에, 함께 쓰는 데이터는 일반 함수 인자처럼 전달할 수 있어요.
let byName = Integer 2
let byFullName = Number.Invalid
구별된 공용체는 _구조적 동등성_을 가져요. 즉, 같은 케이스이고 (있다면) 같은 데이터를 가진 두 값은 서로 같아요.
구별된 공용체를 다루는 가장 좋은 방법은 식별자 패턴을 사용한 패턴 매칭이에요:
let describe number =
match number with
| Integer i -> sprintf "Integer: %d" i
| Float d -> sprintf "Float: %f" d
| Invalid -> "Invalid"