# 機能設計書 71-flatten

## 概要

本ドキュメントは、Hack Standard Library（HSL）のVec名前空間が提供する`flatten`関数の機能設計を記述する。この関数は、ネストしたTraversableを1レベルのみ平坦化し、単一のvecとして返却する機能を提供する。

### 本機能の処理概要

`Vec\flatten`関数は、Traversable<Container<Tv>>型のネストしたコレクションを受け取り、内部のすべての要素を単一のvec<Tv>に結合する機能を提供する。PHPやJavaScriptにおける`array_merge`や`flat`に相当する機能をHack言語で型安全に実装している。

**業務上の目的・背景**：データ処理において、複数のコレクションを統合する操作は頻繁に発生する。例えば、複数のAPIレスポンスを結合する場合や、グループ化されたデータを一括処理する場合など、ネストした構造を平坦化する必要がある。`flatten`関数は、このような処理をシンプルかつ型安全に記述することを可能にし、開発者の生産性向上に寄与する。

**機能の利用シーン**：
- 複数のデータソースから取得したコレクションを1つのリストに統合する場合
- グループ化されたデータを一括で処理する前に平坦化する場合
- 可変数のTraversableを動的に結合する場合（固定数の場合は`Vec\concat`を推奨）

**主要な処理内容**：
1. 入力として、Containerの要素を持つTraversableを受け取る
2. 外側のTraversableを順次イテレートする
3. 各Containerの要素を結果のvecに追加する
4. 全ての要素を含む新しいvecを返却する

**関連システム・外部連携**：本機能は純粋な関数であり、外部システムとの連携はない。HSL内部では、Math名前空間などの他のモジュールとの依存関係もない。

**権限による制御**：本機能は純粋関数（Pure Function）であり、権限による制御は適用されない。関数シグネチャの`[]:`は、この関数が副作用を持たないことを示すHackのコンテキスト記法である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 画面なし | - | 本プロジェクトはUIを持たないライブラリ |

## 機能種別

計算処理 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversables | Traversable<Container<Tv>> | Yes | ネストしたコレクション。外側はTraversable、内側の各要素はContainer型 | なし（空コレクションも許容） |

### 入力データソース

関数引数として直接渡される。Containerとして許容される型には、vec、dict、keyset、Vector、Map、Set、ImmVector、ImmMap、ImmSetが含まれる。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | vec<Tv> | 全ての内部要素を連結した新しいvec |

### 出力先

関数の戻り値として呼び出し元に返却される。

## 処理フロー

### 処理シーケンス

```
1. 空のvecを結果として初期化
   └─ $result = vec[]
2. 外側のTraversableをイテレート
   └─ foreach ($traversables as $traversable)
3. 内側のContainerの各要素をイテレート
   └─ foreach ($traversable as $value)
4. 要素を結果vecに追加
   └─ $result[] = $value
5. 完成した結果vecを返却
   └─ return $result
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[result = vec空配列を初期化]
    B --> C{traversablesに次の要素があるか}
    C -->|Yes| D[次のtraversableを取得]
    D --> E{traversable内に次の要素があるか}
    E -->|Yes| F[valueを取得]
    F --> G[resultにvalueを追加]
    G --> E
    E -->|No| C
    C -->|No| H[resultを返却]
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-71-01 | 1レベル平坦化 | ネストは1レベルのみ解消される | 常時 |
| BR-71-02 | 順序保持 | 入力順序が出力で保持される | 常時 |
| BR-71-03 | 空入力処理 | 空のTraversableは空のvecを返す | 入力が空の場合 |
| BR-71-04 | キー破棄 | Mapなどのキー付きコンテナのキーは破棄される | KeyedContainer入力時 |

### 計算ロジック

特別な計算ロジックはない。純粋な連結処理を行う。

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数は例外をスローしない | - |

### リトライ仕様

本機能にリトライ仕様はない。

## トランザクション仕様

本機能はデータベーストランザクションを使用しない。

## パフォーマンス要件

- 時間計算量: O(n) - nは全要素の合計数
- 空間計算量: O(n) - 結果格納用のvec

## セキュリティ考慮事項

本機能は純粋関数であり、特別なセキュリティ考慮事項はない。入力データのサニタイズや認証・認可の処理は呼び出し元の責務となる。

## 備考

- 固定数のTraversableを連結する場合は、`Vec\concat`の使用を推奨する
- 関数属性`<<__NoAutoLikes>>`により、自動的なlike型推論が無効化されている
- コンテキスト`[]:`は、この関数が純粋で副作用を持たないことを示す

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

`flatten`関数で扱うデータ型は、Hackの組み込み型である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Hack言語組み込み型 | - | Traversable<T>とContainer<T>の違いを理解する。Containerはカウント可能でインデックスアクセス可能、TraversableはIterator的 |

**読解のコツ**: HackにおけるTraversableはPHPのIterableに相当し、foreachで反復可能な型。ContainerはTraversableのサブタイプで、C\count()やインデックスアクセスが可能。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | transform.php | `src/vec/transform.php` | flatten関数の定義と実装を確認 |

**主要処理フロー**:
1. **77-78行目**: 関数シグネチャ - `Traversable<Container<Tv>>`を受け取り`vec<Tv>`を返す
2. **79行目**: 空のvecで結果を初期化
3. **80-84行目**: 二重foreachで全要素を結果に追加
4. **85行目**: 結果を返却

#### Step 3: テストケースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | VecTransformTest.php | `tests/vec/VecTransformTest.php` | flatten関数のテストケースを確認 |

**主要処理フロー**:
- **91-113行目**: provideTestFlattenメソッドでテストデータを提供
- **92-96行目**: 空配列のテストケース
- **97-101行目**: 空のvec、Vector、Map、Setの平坦化
- **103-111行目**: 様々な型（vec、Vector、Map、Iterator）の混合ケース
- **115-121行目**: 実際のテスト実行メソッド

### プログラム呼び出し階層図

```
呼び出し元コード
    │
    └─ Vec\flatten($traversables)
           │
           └─ foreach ループ（二重）
                  └─ 結果vecへの要素追加
```

### データフロー図

```
[入力]                           [処理]                      [出力]

Traversable<Container<Tv>>  ───▶  二重foreachループ  ───▶  vec<Tv>
  例: vec[                         各要素を順次追加         例: vec[
    vec[1, 2],                                                1, 2,
    vec[3, 4]                                                 3, 4
  ]                                                         ]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| transform.php | `src/vec/transform.php` | ソース | flatten関数の実装 |
| VecTransformTest.php | `tests/vec/VecTransformTest.php` | テスト | flatten関数のユニットテスト |
| combine.php | `src/vec/combine.php` | ソース | 関連関数concat, zipの実装 |
