# 機能設計書 28-シーケンス操作（Seq）

## 概要

本ドキュメントは、FSharp.Coreライブラリにおけるシーケンス操作モジュール（Seq）の設計を記述する。この機能は、F#のシーケンス（遅延評価リスト）に対する各種操作関数群を提供する。

### 本機能の処理概要

F#のシーケンス（seq<'T> = IEnumerable<'T>）に対する操作関数を提供するモジュール。シーケンスは遅延評価されるため、無限シーケンスや大規模データの処理に適している。map、filter、fold等の高階関数から、head、take、skip等の基本操作まで、シーケンス処理に必要な関数を網羅的に提供する。

**業務上の目的・背景**：シーケンスは.NETのIEnumerable<T>と互換性があり、LINQやデータベースクエリ、ファイル読み込み等との連携が容易。遅延評価により、必要な要素のみを計算するため、メモリ効率と処理効率が高い。

**機能の利用シーン**：大規模データの逐次処理、無限シーケンス（例：フィボナッチ数列）の生成、データベースクエリ結果の処理、ファイルの行単位読み込みなどで利用される。

**主要な処理内容**：
1. 生成関数: init, initInfinite, unfold, empty, singleton
2. 変換関数: map, mapi, map2, collect, cache
3. フィルタリング: filter, choose, where, takeWhile, skipWhile
4. 集約関数: fold, reduce, scan, sum, average
5. 検索関数: find, tryFind, exists, forall
6. 分割・結合: take, skip, append, concat
7. 遅延評価制御: cache, delay

**関連システム・外部連携**：.NET IEnumerable<T>との相互運用。

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ライブラリ機能のためUI関連なし |

## 機能種別

コレクション操作 / 遅延評価 / ユーティリティライブラリ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source | seq<'T> | Yes | 操作対象のシーケンス | null不可 |
| mapping | 'T -> 'U | 関数依存 | 変換関数 | - |
| predicate | 'T -> bool | 関数依存 | 条件判定関数 | - |
| folder | 'State -> 'T -> 'State | 関数依存 | 畳み込み関数 | - |

### 入力データソース

呼び出し元のF#コード、またはIEnumerable<T>を実装するデータソース。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 結果シーケンス | seq<'U> | 変換後のシーケンス（遅延評価） |
| 単一値 | 'T または 'State | 集約結果（即時評価） |
| Option | 'T option | 検索結果（見つからない場合None） |
| bool | bool | 条件判定結果 |

### 出力先

呼び出し元に返却。

## 処理フロー

### 処理シーケンス

```
1. シーケンス操作関数の呼び出し
   └─ 多くの関数は遅延評価オブジェクトを返す
2. 遅延シーケンスの構築
   └─ IEnumerable<T>を実装するオブジェクトを生成
3. 列挙時に実際の計算を実行
   └─ GetEnumerator() → MoveNext() → Current
4. 必要に応じて結果をキャッシュ
   └─ cache関数で再列挙時の再計算を防止
```

### フローチャート

```mermaid
flowchart TD
    A[開始: Seq.xxx呼び出し] --> B{評価タイミング}
    B -->|遅延評価| C[遅延シーケンスを構築]
    B -->|即時評価| D[すべての要素を評価]
    C --> E[IEnumerableを返却]
    D --> F[結果を計算して返却]
    E --> G{シーケンスが列挙される}
    G -->|MoveNext| H[次の要素を計算]
    H --> I{さらに要素がある?}
    I -->|Yes| G
    I -->|No| J[列挙完了]
    F --> K[終了]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 遅延評価 | シーケンス操作の多くは遅延評価される | map, filter等 |
| BR-02 | 副作用の注意 | 遅延評価のため副作用のタイミングに注意 | 常時 |
| BR-03 | null不許可 | シーケンス引数にnullは許可されない | すべての関数 |
| BR-04 | 無限シーケンス | 一部の関数は無限シーケンスをサポート | initInfinite等 |

### 計算ロジック

```fsharp
// map の概念的な実装
let map mapping source =
    seq {
        for x in source do
            yield mapping x
    }

// filter の概念的な実装
let filter predicate source =
    seq {
        for x in source do
            if predicate x then
                yield x
    }
```

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

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

該当なし。純粋なインメモリ操作（ただしデータソースがDBクエリの場合あり）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentNullException | シーケンスがnullの場合 | 有効なシーケンスを渡す |
| - | InvalidOperationException | 空シーケンスにhead等を呼び出した場合 | tryHead等を使用 |
| - | InvalidOperationException | 要素が不足している場合（take等） | 事前にlengthをチェック |

### リトライ仕様

リトライは不要。ただしシーケンスの再列挙で再計算が発生する点に注意。

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

該当なし。

## パフォーマンス要件

- 遅延評価により、必要な要素のみ計算
- cacheで再列挙時の再計算を防止可能
- 大規模データでも定数メモリで処理可能（ストリーミング）
- length はO(n)（全要素を列挙）

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

- 遅延評価のため、外部データソースへのアクセスタイミングに注意
- 信頼されていないデータの処理でも安全に動作

## 備考

- seq<'T>はIEnumerable<'T>のエイリアス
- シーケンス式 `seq { ... }` で独自シーケンスを定義可能
- Generator/IEnumeratorベースの内部実装
- ArrayBuilderで効率的な配列生成をサポート

---

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

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

### 推奨読解順序

#### Step 1: 内部構造を理解する

まず、シーケンスの内部実装構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.ArrayBuilder（22-46行目） |
| 1-2 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.IEnumerator.MapEnumerator（84-122行目） |
| 1-3 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.Generator（417-500行目） |

**読解のコツ**: シーケンスはIEnumerator<T>を返すIEnumerable<T>として実装される。MapEnumeratorは遅延評価のベース。

#### Step 2: 基本関数を理解する

シーケンスの基本操作関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.IEnumerator.tryItem（52-55行目） |
| 2-2 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.IEnumerator.nth（57-76行目） |
| 2-3 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.IEnumerator.map（124-136行目） |

**主要処理フロー**:
- **52-55行目**: tryItemはMoveNext()で要素を探す
- **124-136行目**: mapはMapEnumeratorを継承して各要素を変換

#### Step 3: 高階関数を理解する

map、filter等の変換関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.IEnumerator.filter（261-290行目） |
| 3-2 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.IEnumerator.choose（227-259行目） |
| 3-3 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.IEnumerator.unfold（292-307行目） |

**主要処理フロー**:
- **261-290行目**: filterはMoveNext内でpredicateをチェック
- **292-307行目**: unfoldは状態から次の値を生成

#### Step 4: ジェネレータを理解する

シーケンス式の内部実装であるGeneratorを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.Generator.Step型（420-423行目） |
| 4-2 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.Generator.GenerateThen（455-480行目） |
| 4-3 | seq.fs | `src/FSharp.Core/seq.fs` | Internal.Generator.bindG（482-483行目） |

**主要処理フロー**:
- **420-423行目**: Step型はStop, Yield, Gotoの3状態
- **455-480行目**: GenerateThenでジェネレータを連結（yield!の実装）

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

```
Seq モジュール (seq.fs)
    │
    ├─ Internal.ArrayBuilder
    │      ├─ addToBuilder
    │      └─ builderToArray
    │
    ├─ Internal.IEnumerator
    │      ├─ MapEnumerator<'T>
    │      │      ├─ DoMoveNext (抽象)
    │      │      └─ Dispose
    │      ├─ map (MapEnumerator実装)
    │      ├─ mapi
    │      ├─ map2
    │      ├─ filter
    │      ├─ choose
    │      └─ unfold
    │
    ├─ Internal.Generator
    │      ├─ Step<'T> (Stop | Yield | Goto)
    │      ├─ Generator<'T> (Apply, Disposer)
    │      ├─ GenerateThen<'T>
    │      └─ bindG
    │
    └─ Seq (公開API)
           ├─ map → IEnumerator.map
           ├─ filter → IEnumerator.filter
           ├─ fold (即時評価)
           └─ toArray (ArrayBuilder使用)
```

### データフロー図

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

seq<'T> ───▶ 遅延操作構築 ───▶ IEnumerable<'U> ───▶ 列挙時に計算
    │              │                │
    │              ├─ map: MapEnumerator
    │              ├─ filter: FilterEnumerator
    │              └─ unfold: UnfoldEnumerator
    │
    └─ データソース (配列, リスト, DB, ファイル等)

列挙時:
GetEnumerator() → MoveNext() → Current → 結果取得
                      ↓
              ソースから次の要素を取得
              変換/フィルタを適用
              結果をCurrentに設定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| seq.fs | `src/FSharp.Core/seq.fs` | ソース | Seqモジュールのメイン実装 |
| seq.fsi | `src/FSharp.Core/seq.fsi` | シグネチャ | 公開APIの定義 |
| IEnumerator.fs | `src/FSharp.Core/IEnumerator.fs` | ソース | IEnumeratorヘルパー |
| Linq.fs | `src/FSharp.Core/Linq.fs` | ソース | LINQ統合 |
