データ構造とは、複数の値をどのような形でまとめるかという設計です。


4.1 直積型

複数の値を同時に持つ構造です。

ユーザー = 名前 × 年齢 × メールアドレス

多くの言語ではクラス、構造体、レコードなどで表現します。

struct User {
    name: String,
    age: u32,
}
@dataclass
class User:
    name: str
    age: int

「名前と年齢の両方を持つ」ため、数学的には直積型と呼ばれます。


4.2 直和型

複数の候補のうち、いずれか一つを取る構造です。

結果 = 成功 または 失敗

Rustではenumで表現します。

enum Result<T, E> {
    Ok(T),
    Err(E),
}

TypeScriptではUnion型で表現できます。

type Result<T> =
  | { type: "success"; value: T }
  | { type: "error"; message: string };

直和型は、状態を安全に表現するための非常に重要な概念です。


4.3 代数的データ型

直積型と直和型を組み合わせたデータ構造を、代数的データ型と呼びます。

例えば注文状態を次のように表せます。

type OrderStatus =
  | { type: "draft" }
  | { type: "paid"; paidAt: Date }
  | { type: "shipped"; trackingNumber: string }
  | { type: "cancelled"; reason: string };

状態ごとに必要なデータが異なることを、型として表現しています。

悪い設計では、すべてを一つの構造へ入れます。

type Order = {
  status: string;
  paidAt?: Date;
  trackingNumber?: string;
  cancellationReason?: string;
};

この場合、矛盾した状態を作れます。

status = draft
trackingNumber = 存在する
cancellationReason = 存在する

直和型を使うと、不正な状態を作りにくくできます。


4.4 コレクション

代表的なコレクションには次があります。

構造 特徴
配列・リスト 順序付きの値
集合 重複しない値
マップ・辞書 キーと値の対応
キュー 先入れ先出し
スタック 後入れ先出し

言語間で名前は違っても、データ構造としての性質は共通です。