# 機能設計書 27-リスト操作（List）

## 概要

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

### 本機能の処理概要

F#のリスト（'T list）に対する操作関数を提供するモジュール。リストはF#の最も基本的な不変データ構造であり、関数型プログラミングの中心的な役割を果たす。map、filter、fold等の高階関数から、head、tail、cons等の基本操作まで、リスト処理に必要な関数を網羅的に提供する。

**業務上の目的・背景**：リストはF#プログラミングの中核をなすデータ構造であり、再帰的なデータ処理や関数型プログラミングのパターンで広く使用される。Listモジュールは、リストを効率的かつ安全に操作するための統一的なAPIを提供し、不変性を保証した状態でのデータ変換を可能にする。

**機能の利用シーン**：データの変換処理、フィルタリング、集計、パターンマッチによる分解、再帰的なデータ処理など、リストを使用するあらゆる場面で利用される。

**主要な処理内容**：
1. 基本操作: head, tail, length, isEmpty, cons
2. 変換関数: map, mapi, map2, map3, collect
3. フィルタリング: filter, choose, where
4. 集約関数: fold, foldBack, reduce, scan, sum, average
5. 検索関数: find, tryFind, findIndex, exists, forall
6. ソート関数: sort, sortBy, sortWith, sortDescending
7. 分割・結合: take, skip, splitAt, append, concat, rev

**関連システム・外部連携**：Microsoft.FSharp.Primitives.Basics.Listに低レベル実装を委譲。

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| list | 'T list | Yes | 操作対象のリスト | パターンマッチで処理 |
| mapping | 'T -> 'U | 関数依存 | 変換関数 | - |
| predicate | 'T -> bool | 関数依存 | 条件判定関数 | - |
| folder | 'State -> 'T -> 'State | 関数依存 | 畳み込み関数 | - |

### 入力データソース

呼び出し元のF#コード。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 結果リスト | 'U list | 変換後のリスト |
| 単一値 | 'T または 'State | 集約結果 |
| Option | 'T option | 検索結果（見つからない場合None） |
| bool | bool | 条件判定結果 |

### 出力先

呼び出し元に返却。

## 処理フロー

### 処理シーケンス

```
1. パターンマッチでリストを分解
   └─ 空リスト [] または 要素 :: 残り
2. 再帰的に処理を実行
   └─ 末尾再帰最適化を活用
3. 結果を構築して返却
   └─ 新しいリストを生成（不変性を維持）
```

### フローチャート

```mermaid
flowchart TD
    A[開始: List.xxx呼び出し] --> B{リストのパターン}
    B -->|空リスト []| C[基底ケースを処理]
    B -->|h :: t| D[先頭要素と残りを分解]
    D --> E[先頭要素を処理]
    E --> F[残りのリストで再帰呼び出し]
    F --> G[結果を結合]
    C --> H[結果を返却]
    G --> H
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 不変性 | 元のリストは変更されない | すべての関数 |
| BR-02 | 空リスト処理 | 空リストに対する head/tail は例外 | 該当関数 |
| BR-03 | 長さ一致 | map2等では入力リストの長さが一致すること | 複数リストを受け取る関数 |
| BR-04 | 末尾再帰 | 大きなリストでもスタックオーバーフローを防止 | 該当関数 |

### 計算ロジック

```fsharp
// map の実装例（95-97行目参照）
let map mapping list =
    Microsoft.FSharp.Primitives.Basics.List.map mapping list

// fold の実装例（286-297行目参照）
let fold<'T, 'State> folder (state: 'State) (list: 'T list) =
    match list with
    | [] -> state
    | _ ->
        let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(folder)
        let mutable acc = state
        for x in list do
            acc <- f.Invoke(acc, x)
        acc
```

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

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

該当なし。純粋なインメモリ操作。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentException | 空リストに対してhead/tailを呼び出した場合 | 事前にisEmptyでチェック、またはtryHead/tryLast使用 |
| - | KeyNotFoundException | find系で要素が見つからない場合 | tryFind系を使用 |
| - | InvalidOperationException | take/skipで要素が不足している場合 | 事前にlengthをチェック |
| - | ArgumentException | 異なる長さのリストをmap2等に渡した場合 | 事前に長さを確認 |

### リトライ仕様

リトライは不要。純粋関数のため同じ入力には同じ結果。

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

該当なし。

## パフォーマンス要件

- length はO(n)（リストは連結リストのため）
- head/tail はO(1)
- append はO(n)（最初のリストの長さに比例）
- rev はO(n)
- sort系はO(n log n)
- foldBack は配列に変換してから処理（スタックオーバーフロー防止）

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

- 不変データ構造のため並行アクセスに安全
- 信頼されていないデータの処理でも安全に動作

## 備考

- リストは先頭へのアクセスがO(1)、末尾へのアクセスがO(n)
- 大きなリストの末尾再帰でない処理は配列に変換して実行
- `@` 演算子はappendと同等

---

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

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

### 推奨読解順序

#### Step 1: モジュール構造を理解する

まず、Listモジュールの基本構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | list.fs | `src/FSharp.Core/list.fs` | モジュール宣言と属性（13-15行目） |
| 1-2 | list.fs | `src/FSharp.Core/list.fs` | ヘルパー関数（17-22行目）checkNonNull, indexNotFound |

**読解のコツ**: 配列モジュールと同様の構造だが、リストはnullを許容しないためcheckNonNullの使用頻度が低い。

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

リストの基本操作関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | list.fs | `src/FSharp.Core/list.fs` | length（24-26行目） |
| 2-2 | list.fs | `src/FSharp.Core/list.fs` | head/tryHead（152-162行目） |
| 2-3 | list.fs | `src/FSharp.Core/list.fs` | tail（164-168行目） |
| 2-4 | list.fs | `src/FSharp.Core/list.fs` | isEmpty（170-174行目） |
| 2-5 | list.fs | `src/FSharp.Core/list.fs` | empty（149-150行目） |

**主要処理フロー**:
- **24-26行目**: lengthはlist.Lengthプロパティを使用
- **152-156行目**: headはパターンマッチで最初の要素を取得
- **164-168行目**: tailはパターンマッチで残りを取得

#### Step 3: 変換関数を理解する

map、filter等の高階関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | list.fs | `src/FSharp.Core/list.fs` | map（95-97行目） |
| 3-2 | list.fs | `src/FSharp.Core/list.fs` | mapi（99-101行目） |
| 3-3 | list.fs | `src/FSharp.Core/list.fs` | map2（282-284行目） |
| 3-4 | list.fs | `src/FSharp.Core/list.fs` | rev（40-42行目） |

**主要処理フロー**:
- **95-97行目**: mapはBasics.List.mapに委譲
- **40-42行目**: revはBasics.List.revに委譲（末尾再帰最適化済み）

#### Step 4: 集約関数を理解する

fold、reduce等の畳み込み関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | list.fs | `src/FSharp.Core/list.fs` | fold（286-297行目） |
| 4-2 | list.fs | `src/FSharp.Core/list.fs` | foldBack（339-354行目） |
| 4-3 | list.fs | `src/FSharp.Core/list.fs` | reduce（303-307行目） |
| 4-4 | list.fs | `src/FSharp.Core/list.fs` | exists（450-452行目） |
| 4-5 | list.fs | `src/FSharp.Core/list.fs` | forall（446-448行目） |

**主要処理フロー**:
- **286-297行目**: foldはforループで畳み込み（mutableなアキュムレータ使用）
- **339-354行目**: foldBackは配列に変換してから逆順処理（スタックオーバーフロー防止）

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

```
List モジュール (list.fs)
    │
    ├─ 基本操作
    │      ├─ length (list.Length)
    │      ├─ head / tryHead (パターンマッチ)
    │      ├─ tail (パターンマッチ)
    │      ├─ isEmpty (パターンマッチ)
    │      └─ empty ([] 定数)
    │
    ├─ 変換操作 → Basics.List
    │      ├─ map
    │      ├─ mapi
    │      ├─ collect → choose
    │      └─ rev
    │
    ├─ 集約操作
    │      ├─ fold (for ループ)
    │      ├─ foldBack (配列変換)
    │      ├─ reduce (fold使用)
    │      └─ scan
    │
    ├─ 検索操作
    │      ├─ find / tryFind (再帰)
    │      ├─ exists / forall → Basics.List
    │      └─ contains
    │
    └─ Microsoft.FSharp.Primitives.Basics.List (低レベル実装)
           ├─ map (末尾再帰)
           ├─ rev
           ├─ concat
           └─ その他最適化実装
```

### データフロー図

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

'T list ───▶ パターンマッチ ───▶ 各操作関数 ───▶ 'U list / 'T / bool
    │              │                │
    │              ├─ [] → 基底ケース
    │              └─ h::t → 再帰処理
    │
    └─ mapping/predicate/folder (関数引数)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| list.fs | `src/FSharp.Core/list.fs` | ソース | Listモジュールのメイン実装 |
| list.fsi | `src/FSharp.Core/list.fsi` | シグネチャ | 公開APIの定義 |
| local.fs | `src/FSharp.Core/local.fs` | ソース | 内部ヘルパー関数 |
| prim-types.fs | `src/FSharp.Core/prim-types.fs` | ソース | 基本型とPrimitives.Basics.List |
