# 機能設計書 45-Nullable型

## 概要

本ドキュメントは、F#コアライブラリにおけるNullable型のサポート機能の設計を記述する。

### 本機能の処理概要

Nullable型サポート機能は、.NETのSystem.Nullable<T>（null許容値型）をF#から自然に扱うための演算子とユーティリティ関数を提供する。データベースアクセスやC#との相互運用において重要な役割を果たす。

**業務上の目的・背景**：データベースのNULL値やC#コードとの相互運用において、null許容値型の操作が必要になる。F#は本来null安全な言語だが、.NET相互運用のためにNullable<T>を扱う必要がある。本機能により、Nullable値を安全かつ簡潔に操作できる。

**機能の利用シーン**：
- データベースからのNULL可能な値の取得
- C#ライブラリとの相互運用
- クエリ式（query { }）内でのNullable演算
- オプショナルな数値データの処理

**主要な処理内容**：
1. Nullable値同士の比較演算子の提供（?>=, ?>, ?<=, ?<, ?=, ?<>）
2. Nullable値と非Nullable値の比較演算子
3. Nullable値の算術演算子（?+, ?-, ?*, ?/, ?%）
4. Nullable値の型変換関数

**関連システム・外部連携**：System.Nullable<T>、LINQクエリ、データベースアクセス

**権限による制御**：特になし（純粋なライブラリ機能）

## 関連画面

本機能はコアライブラリ機能のため、直接関連する画面はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

型操作 / 演算子

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | Nullable<'T> | Yes | Nullable値（左オペランド） | - |
| y | 'T または Nullable<'T> | Yes | 比較/演算対象（右オペランド） | - |

### 入力データソース

プログラムコード内のNullable値

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 比較結果 | bool | 比較演算の結果 |
| 演算結果 | Nullable<'T> | 算術演算の結果 |
| 変換結果 | Nullable<'U> | 型変換の結果 |

### 出力先

メモリ上の値

## 処理フロー

### 処理シーケンス

```
1. Nullable値の受け取り
   └─ HasValueプロパティで値の存在を確認
2. 演算の実行
   └─ 値が存在する場合: 実際の値で演算
   └─ 値が存在しない場合: false（比較）またはNullable()（算術）を返却
3. 結果の返却
   └─ bool または Nullable<'T>
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{HasValue?}
    B -->|Yes| C[値を取り出す]
    B -->|No| D[デフォルト結果を返却]
    C --> E{演算種別}
    E -->|比較| F[比較演算を実行]
    E -->|算術| G[算術演算を実行]
    F --> H[boolを返却]
    G --> I[Nullable結果を返却]
    D --> J[終了]
    H --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Null伝播 | 片方がNullの場合、算術演算結果はNull | 算術演算 |
| BR-02 | Null比較 | 片方がNullの場合、比較結果はfalse | 比較演算（?=?以外） |
| BR-03 | Null等価 | 両方Nullの場合、?=?はtrue | ?=?演算子 |

### 計算ロジック

比較演算子（Nullable<'T> と 'T）:
| 演算子 | 意味 | 左がNull時 |
|--------|------|-----------|
| `?>=` | Nullable >= 値 | false |
| `?>` | Nullable > 値 | false |
| `?<=` | Nullable <= 値 | false |
| `?<` | Nullable < 値 | false |
| `?=` | Nullable = 値 | false |
| `?<>` | Nullable <> 値 | true |

比較演算子（'T と Nullable<'T>）:
| 演算子 | 意味 | 右がNull時 |
|--------|------|-----------|
| `>=?` | 値 >= Nullable | false |
| `>?` | 値 > Nullable | false |
| `<=?` | 値 <= Nullable | false |
| `<?` | 値 < Nullable | false |
| `=?` | 値 = Nullable | false |
| `<>?` | 値 <> Nullable | true |

比較演算子（Nullable<'T> と Nullable<'T>）:
| 演算子 | 意味 | どちらかNull時 |
|--------|------|---------------|
| `?>=?` | 両Nullable比較 | false |
| `?>?` | 両Nullable比較 | false |
| `?<=?` | 両Nullable比較 | false |
| `?<?` | 両Nullable比較 | false |
| `?=?` | 両Nullable比較 | 両方Nullならtrue |
| `?<>?` | 両Nullable比較 | 片方のみNullならtrue |

算術演算子:
| 演算子 | 意味 | Null含む場合 |
|--------|------|-------------|
| `?+`, `+?`, `?+?` | 加算 | Nullable() |
| `?-`, `-?`, `?-?` | 減算 | Nullable() |
| `?*`, `*?`, `?*?` | 乗算 | Nullable() |
| `?/`, `/?`, `?/?` | 除算 | Nullable() |
| `?%`, `%?`, `?%?` | 剰余 | Nullable() |

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

本機能はデータベースを直接操作しない。データベースアクセスライブラリと組み合わせて使用される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| DivideByZeroException | 実行時エラー | Nullable値で0除算 | 0チェックを追加 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- inline関数により、呼び出しオーバーヘッドを最小化
- 値型のボックス化を回避

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

特になし

## 備考

NullableOperatorsモジュールの演算子は、LINQクエリ式内で自動的に利用可能になる。

---

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

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

### 推奨読解順序

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

Nullable型の基本を理解する。System.Nullable<T>はF#外で定義されているため、このファイルは演算子と関数のみを定義する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | NullableOperatorsモジュール（11-155行目）で演算子を把握 |
| 1-2 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | Nullableモジュール（159-305行目）で変換関数を確認 |

**読解のコツ**: 演算子名の`?`の位置がNullable引数の位置を示す（?>=は左がNullable、>=?は右がNullable）

#### Step 2: 比較演算子を理解する

Nullable値の比較演算子の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | **12-28行目**: Nullable vs 値 の比較演算子 |
| 2-2 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | **30-46行目**: 値 vs Nullable の比較演算子 |
| 2-3 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | **48-65行目**: Nullable vs Nullable の比較演算子 |

**主要処理フロー**:
- **12-13行目**: `(?>=)` - HasValueをチェックし、値があれば比較
- **60-62行目**: `(?=?)` - 両方Nullの場合もtrueを返す特殊な等価比較

#### Step 3: 算術演算子を理解する

Nullable値の算術演算子の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | **67-83行目**: 加算演算子 `?+`, `+?`, `?+?` |
| 3-2 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | **85-101行目**: 減算演算子 `?-`, `-?`, `?-?` |
| 3-3 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | **103-155行目**: 乗算・除算・剰余演算子 |

**主要処理フロー**:
- **67-71行目**: `(?+)` - 左がNullableの場合、HasValueチェック後に加算
- **79-83行目**: `(?+?)` - 両方Nullableの場合、両方のHasValueをチェック

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

Nullable値の型変換関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | **160-165行目**: uint8変換 |
| 4-2 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | **258-263行目**: float変換 |
| 4-3 | Nullable.fs | `src/FSharp.Core/Nullable.fs` | **293-298行目**: decimal変換 |

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

```
[演算子使用例: x ?+ y]
    │
    └─ NullableOperators.(?+)
           │
           ├─ x.HasValue チェック
           │      │
           │      ├─ true → Nullable(x.Value + y)
           │      │
           │      └─ false → Nullable()

[型変換例: Nullable.int nullableValue]
    │
    └─ Nullable.int
           │
           ├─ value.HasValue チェック
           │      │
           │      ├─ true → Nullable(int value.Value)
           │      │
           │      └─ false → Nullable()
```

### データフロー図

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

Nullable<int>     ───▶  HasValue チェック       ───▶  比較結果/演算結果
  x = Nullable(5)       (値の存在確認)                  bool / Nullable<'T>
    │
    ▼
演算子/関数       ───▶  値の取り出しと演算     ───▶  結果
  ?+ / Nullable.int    (Value プロパティ)             Nullable(結果) or Nullable()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Nullable.fs | `src/FSharp.Core/Nullable.fs` | ソース | Nullable演算子・関数の定義 |
| Query.fs | `src/FSharp.Core/Query.fs` | ソース | クエリ式でのNullable演算サポート |
