# 機能設計書 74-concat

## 概要

本ドキュメントは、Hack Standard Library（HSL）のVec名前空間が提供する`concat`関数の機能設計を記述する。この関数は、複数のTraversableを連結し、単一のvecとして返却する機能を提供する。

### 本機能の処理概要

`Vec\concat`関数は、固定数のTraversableを受け取り、それらを順番に連結した新しいvecを返却する。可変長引数（variadic）を使用して、最初のTraversableと追加のContainerを任意の数だけ受け取ることができる。

**業務上の目的・背景**：複数のデータソースからのコレクションを結合する操作は、アプリケーション開発において頻繁に発生する。例えば、ページネーションされたAPIレスポンスを結合する、複数のフィルタ結果を統合する、ヘッダーとボディのデータを結合するなどのケースである。`concat`関数は、このような連結処理を型安全かつ効率的に実行することを可能にする。

**機能の利用シーン**：
- 複数のAPIレスポンスを1つのリストに結合する
- ヘッダー行とデータ行を結合してCSVデータを構築する
- 複数のフィルタ結果を統合する
- プレフィックスやサフィックスを配列に追加する

**主要な処理内容**：
1. 入力として最初のTraversableと追加のContainerを可変長引数で受け取る
2. 最初のTraversableをvecに変換して結果を初期化する
3. 各追加Containerの要素を順次結果vecに追加する
4. すべての要素を含む新しいvecを返却する

**関連システム・外部連携**：本機能は純粋な関数であり、外部システムとの連携はない。

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

## 関連画面

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

## 機能種別

計算処理 / データ結合

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $first | Traversable<Tv> | Yes | 最初のコレクション | なし（空コレクションも許容） |
| ...$rest | Container<Tv> | No | 追加のコレクション（可変長引数） | なし |

### 入力データソース

関数引数として直接渡される。最初の引数はTraversable型、追加の引数はContainer型である必要がある。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | vec<Tv> | 全てのコレクションを連結した新しいvec |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 最初のTraversableをvecに変換（レガシー配列マークをクリア）
   └─ $result = cast_clear_legacy_array_mark($first)
2. 追加のContainerをイテレート
   └─ foreach ($rest as $traversable)
3. 各Containerの要素を結果vecに追加
   └─ foreach ($traversable as $value)
       └─ $result[] = $value
4. 完成した結果vecを返却
   └─ return $result
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[firstをvecに変換してresultを初期化]
    B --> C{restに次のコレクションがあるか}
    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-74-01 | 順序保持 | 入力順序が出力で保持される | 常時 |
| BR-74-02 | 連結順序 | $first, $rest[0], $rest[1]...の順で連結 | 常時 |
| BR-74-03 | 空入力処理 | 空のコレクションも連結可能（要素なしとして扱う） | 入力が空の場合 |
| BR-74-04 | キー破棄 | Mapなどのキー付きコンテナのキーは破棄される | KeyedContainer入力時 |
| BR-74-05 | 型統一 | すべてのコレクションは同一型Tvの要素を持つ必要がある | 常時 |

### 計算ロジック

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

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

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

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

## パフォーマンス要件

- 時間計算量: O(n + m) - nは$firstのサイズ、mは$rest全体の合計サイズ
- 空間計算量: O(n + m) - 結果格納用のvec

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

本機能は純粋関数であり、特別なセキュリティ考慮事項はない。

## 備考

- 可変数のTraversableを連結する場合は、`Vec\flatten`の使用を推奨する
- 内部関数`cast_clear_legacy_array_mark`を使用してレガシー配列マークをクリアする

---

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

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

### 推奨読解順序

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

`concat`関数は可変長引数を使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Hack言語組み込み型 | - | Traversable<Tv>とContainer<Tv>の違い、可変長引数の記法を理解する |

**読解のコツ**: `...$rest`はHackの可変長引数（variadic parameter）を示す。Container<Tv>は、Traversableよりも機能が豊富で、C\count()やインデックスアクセスが可能。

#### Step 2: 補助関数を理解する

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

**主要処理フロー**:
- **18-24行目**: レガシー配列マークをクリアしてvecに変換
- **21-23行目**: 既にvecの場合はarray_unmark_legacyを適用、そうでなければvec()でキャスト

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

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

**主要処理フロー**:
1. **25-28行目**: 関数シグネチャ - $firstと可変長引数$restを受け取る
2. **29行目**: cast_clear_legacy_array_markで最初のTraversableをvecに変換
3. **30-34行目**: 二重foreachで追加のContainerの要素を結果に追加
4. **35行目**: 結果を返却

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

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

**主要処理フロー**:
- **17-40行目**: provideTestConcatメソッドでテストデータを提供
- **19行目**: 空vecと空restのテストケース
- **20-29行目**: 空の様々な型（dict、Vector、Map、Set）のテスト
- **30-38行目**: 実際のデータを使った連結テスト
- **42-49行目**: 実際のテスト実行メソッド

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

```
呼び出し元コード
    │
    └─ Vec\concat($first, ...$rest)
           │
           ├─ cast_clear_legacy_array_mark($first)
           │      └─ vec() または array_unmark_legacy()
           │
           └─ foreach ループ（二重）
                  └─ 各要素を結果vecに追加
```

### データフロー図

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

$first: Traversable<Tv>    ───┐
                              │
                              ├──▶  vecに変換して     ───▶  vec<Tv>
                              │     追加要素を連結
$rest: Container<Tv>...   ───┘

例:
vec['the', 'quick']        ───┐
Vector{'brown', 'fox'}     ───┼──▶  連結処理  ───▶  vec['the', 'quick', 'brown', 'fox', 'over']
Map{'jumped' => 'over'}    ───┘
```

### 関連ファイル一覧

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