# 機能設計書 35-文字列操作（String）

## 概要

本ドキュメントは、F#コアライブラリにおける文字列操作（String）モジュールの機能設計を記述する。Stringモジュールは.NETのSystem.String型を関数型プログラミングスタイルで操作するための関数群を提供する。

### 本機能の処理概要

**業務上の目的・背景**：.NETのSystem.String型はオブジェクト指向的なメソッド呼び出しを基本としているが、F#では関数型プログラミングスタイル（パイプライン演算子やコンビネータの連鎖）が好まれる。Stringモジュールは文字列操作をカリー化された関数として提供することで、関数合成やパイプライン処理を容易にする。また、コレクション操作と同様のAPI（map、iter、filter、collect等）を提供し、文字列を文字のシーケンスとして扱えるようにする。

**機能の利用シーン**：テキスト処理（フォーマット、トリム、検索、置換）、CSV/JSONパース前の前処理、ユーザー入力の正規化、ログメッセージの整形、文字列の分割・結合、コードジェネレーションなど。

**主要な処理内容**：
1. 文字列結合・分割操作（concat、replicate、splitの機能）の提供
2. コレクション操作関数（map、iter、filter、collect、exists、forall、init、mapi、iteri）の提供
3. 長さ取得と空文字列判定（length、IsNullOrEmpty、IsNullOrWhiteSpace）の提供
4. StringBuilder対応の高パフォーマンス処理

**関連システム・外部連携**：.NETのSystem.String型およびSystem.Text.StringBuilderクラスと連携。

**権限による制御**：本機能はライブラリ関数群であり、権限による制御は行わない。

## 関連画面

該当なし（コアライブラリ機能であり、画面は持たない）

## 機能種別

文字列処理 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| str | string | Yes | 操作対象の文字列 | - |
| sep | string | No | 結合時の区切り文字 | - |
| count | int | No | 繰り返し回数 | 負の値でArgumentException |
| mapping | char -> char | No | 文字変換関数 | - |
| predicate | char -> bool | No | 述語関数 | - |
| action | char -> unit | No | 副作用関数 | - |
| collector | char -> string | No | 文字から文字列への変換関数 | - |

### 入力データソース

F#プログラム内の文字列リテラルまたは他の処理からの文字列値。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 結果 | string / bool / int / char | 各関数に応じた戻り値 |

### 出力先

関数の戻り値としてプログラムに返却。

## 処理フロー

### 処理シーケンス

```
1. 文字列の受け取り
   └─ null/空チェック
2. 各操作に応じた処理実行
   └─ map/filter: 文字単位で変換/フィルタリング
   └─ concat: 複数文字列を結合
   └─ replicate: 文字列を繰り返し
3. 結果の返却
   └─ 新しい文字列または集約結果
```

### フローチャート

```mermaid
flowchart TD
    A[文字列操作を開始] --> B{操作種別}
    B -->|concat| C[区切り文字で結合]
    C --> D[新しい文字列を返却]
    B -->|map| E[各文字に関数適用]
    E --> F[StringBuilderで結果構築]
    F --> D
    B -->|filter| G[述語で文字をフィルタ]
    G --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-35-1 | null安全 | String.concatはnull文字列を空文字列として扱う | 入力にnullが含まれる場合 |
| BR-35-2 | 負のcount | replicate関数はcountが負の場合ArgumentExceptionを投げる | count < 0の場合 |
| BR-35-3 | 空シーケンス | concat関数は空シーケンスに対して空文字列を返す | シーケンスが空の場合 |

### 計算ロジック

- `length`: O(1)の時間計算量（.NETのLength プロパティ）
- `concat`: O(n)の時間計算量（文字列の総長に比例）
- `map`/`filter`: O(n)の時間計算量（文字列長に比例）

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

該当なし（メモリ上のデータ操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentException | 実行時例外 | replicateでcountが負の値の場合 | countを0以上に設定 |
| ArgumentNullException | 実行時例外 | null文字列を受け取らない関数にnullを渡した場合 | nullチェックを事前に行う |

### リトライ仕様

該当なし（単純な同期関数のため）

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

該当なし（メモリ上の操作のみ）

## パフォーマンス要件

- 文字列操作はStringBuilderを使用して効率的にメモリを管理
- InlineIfLambda属性によるラムダ式のインライン化で関数呼び出しオーバーヘッドを削減
- length関数はO(1)

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

特になし（純粋な文字列変換関数群）

## 備考

- .NETの文字列は不変であり、String.mapなどの操作は常に新しい文字列を生成する
- 大量の文字列結合にはString.concatが効率的
- Unicode文字（サロゲートペア等）を含む文字列の処理には注意が必要

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | string.fs | `src/FSharp.Core/string.fs` | Stringモジュールの全体構造（1-140行目） |

**読解のコツ**:
- `[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]`属性により、System.String型と衝突しない
- `[<RequireQualifiedAccess>]`属性により、完全修飾名（String.xxx）での呼び出しが必須

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | string.fs | `src/FSharp.Core/string.fs` | concat関数（14-23行目） |
| 2-2 | string.fs | `src/FSharp.Core/string.fs` | replicate関数（35-47行目） |
| 2-3 | string.fs | `src/FSharp.Core/string.fs` | length関数（30-33行目） |

**主要処理フロー**:
1. **14-23行目**: `concat`関数 - 区切り文字で文字列シーケンスを結合
2. **30-33行目**: `length`関数 - 文字列長を取得（nullは0）
3. **35-47行目**: `replicate`関数 - 文字列をcount回繰り返し

#### Step 3: コレクション操作関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | string.fs | `src/FSharp.Core/string.fs` | map関数（76-85行目） |
| 3-2 | string.fs | `src/FSharp.Core/string.fs` | filter関数（100-113行目） |
| 3-3 | string.fs | `src/FSharp.Core/string.fs` | collect関数（115-126行目） |

**主要処理フロー**:
- **76-85行目**: `map`関数 - 各文字にmappingを適用
- **87-98行目**: `mapi`関数 - インデックス付きで各文字にmappingを適用
- **100-113行目**: `filter`関数 - 述語を満たす文字のみを残す
- **115-126行目**: `collect`関数 - 各文字を文字列に変換して結合

#### Step 4: 判定・検索関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | string.fs | `src/FSharp.Core/string.fs` | exists関数（49-58行目） |
| 4-2 | string.fs | `src/FSharp.Core/string.fs` | forall関数（60-74行目） |

**主要処理フロー**:
- **49-58行目**: `exists`関数 - いずれかの文字が述語を満たすか
- **60-74行目**: `forall`関数 - すべての文字が述語を満たすか

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

```
ユーザーコード
    │
    ├─ String.concat sep strings
    │      └─ System.String.Join(sep, strings)
    │
    ├─ String.replicate count str
    │      └─ StringBuilder.Append(str) を count 回
    │             └─ sb.ToString()
    │
    ├─ String.map mapping str
    │      └─ for i in 0 .. str.Length-1 do
    │             └─ sb.Append(mapping str.[i])
    │                    └─ sb.ToString()
    │
    └─ String.filter predicate str
           └─ for c in str do
                  └─ if predicate c then sb.Append(c)
                         └─ sb.ToString()
```

### データフロー図

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

string seq ───────────▶ String.Join ───────────────────▶ string (concat)
+ sep                         │
                              └──▶ 区切り文字で結合

string ───────────────▶ StringBuilder ─────────────────▶ string (replicate)
+ count                       │
                              └──▶ count回append

string ───────────────▶ StringBuilder ─────────────────▶ string (map)
+ (char -> char)              │
                              └──▶ 各文字を変換してappend

string ───────────────▶ StringBuilder ─────────────────▶ string (filter)
+ (char -> bool)              │
                              └──▶ 述語満たす文字のみappend
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| string.fs | `src/FSharp.Core/string.fs` | ソース | Stringモジュールの実装 |
| string.fsi | `src/FSharp.Core/string.fsi` | シグネチャ | Stringモジュールのシグネチャ定義 |
