mcpField
M
m05-type-driven

m05-type-driven

github.com/actionbook開発1.6k3.4k 回インストール9 週間前に更新
リポジトリ

m05-type-driven について

型で不変条件を表し、無効な状態を防ぐための Rust 設計スキルです。newtype から Builder、型状態パターンまで、よく使う型設計の選択指針を示します。

主な機能

  1. 01型で制約を表現
  2. 02一般的な型パターンの選択
  3. 03型状態設計の適用
  4. 04型設計のアンチパターンの特定

活用シーン

  1. 01newtype で意味のある値を表現
  2. 02コンパイル時の状態遷移をモデル化
  3. 03検証付き構築パターンの選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/actionbook/rust-skills --skill m05-type-driven

インストール後、Claude Code で/m05-type-drivenを入力して読み込まれたか確認します。

詳細

型駆動設計

レイヤー 1:言語の仕組み

中心となる問い

型システムによって、無効な状態をどう防げるでしょうか?

実行時チェックに頼る前に、次の点を検討してください。

  • コンパイラーでこのエラーを検出できますか?
  • 無効な状態を表現できないようにできますか?
  • 型で不変条件を表現できますか?

エラー → 設計上の問い

パターンただこう言うのではなく代わりにこう問いかける
プリミティブ型への執着「ただの文字列です」この値は何を表していますか?
ブール値フラグ「is_valid フラグを追加します」状態を型で表せますか?
どこでも Optional「None かどうか確認します」本当に値が存在しないことはあり得ますか?
実行時の検証「無効なら Err を返します」生成時に検証できますか?

思考のヒント

実行時検証を追加する前に、次の点を確認してください。

  1. 型で制約を表現できますか?

    • 数値の範囲 → 範囲制限型または newtype
    • 有効な状態 → 型状態パターン
    • 意味上の区別 → newtype
  2. 検証はいつ可能ですか?

    • 生成時 → 検証済み newtype
    • 状態遷移時 → 型状態
    • 実行時にのみ可能 → 明確なエラーを伴う Result
  3. 不変条件を知る必要があるのは誰ですか?

    • コンパイラー → 型レベルで表現
    • API の利用者 → 明確な型シグネチャ
    • 実行時にのみ必要 → ドキュメント

上へたどる ↑

型設計が不明確な場合:

"Need to validate email format"
    ↑ Ask: Is this a domain value object?
    ↑ Check: m09-domain (Email as Value Object)
    ↑ Check: domain-* (validation requirements)
状況たどる先問い
作成する型m09-domainドメインモデルは何ですか?
状態マシンの設計m09-domain有効な遷移は何ですか?
マーカートレイトの使用m04-zero-cost静的ディスパッチですか、動的ディスパッチですか?

下へたどる ↓

設計から実装へ:

"Need type-safe wrapper for primitives"
    ↓ Newtype: struct UserId(u64);

"Need compile-time state validation"
    ↓ Type State: Connection<Connected>

"Need to track phantom type parameters"
    ↓ PhantomData: PhantomData<T>

"Need capability markers"
    ↓ Marker Trait: trait Validated {}

"Need gradual construction"
    ↓ Builder: Builder::new().field(x).build()

クイックリファレンス

パターン目的例
Newtype型安全性struct UserId(u64);
型状態状態マシンConnection<Connected>
PhantomData分散/ライフタイムPhantomData<&'a T>
マーカートレイト能力フラグtrait Validated {}
ビルダー段階的な構築Builder::new().name("x").build()
シールドトレイト外部からの実装を防止mod private { pub trait Sealed {} }

パターンの例

Newtype
struct Email(String);  // Not just any string

impl Email {
    pub fn new(s: &str) -> Result<Self, ValidationError> {
        // Validate once, trust forever
        validate_email(s)?;
        Ok(Self(s.to_string()))
    }
}
型状態
struct Connection<State>(TcpStream, PhantomData<State>);

struct Disconnected;
struct Connected;
struct Authenticated;

impl Connection<Disconnected> {
    fn connect(self) -> Connection<Connected> { ... }
}

impl Connection<Connected> {
    fn authenticate(self) -> Connection<Authenticated> { ... }
}

選択ガイド

ニーズパターン
プリミティブ型の型安全性Newtype
コンパイル時の状態検証型状態
ライフタイム/分散のマーカーPhantomData
能力フラグマーカートレイト
段階的な構築ビルダー
実装の集合を限定シールドトレイト
ゼロサイズ型のマーカーZST 構造体

アンチパターン

アンチパターン問題点よりよい方法
状態をブール値フラグで表す実行時エラー型状態
意味上の型に String を使う型安全性がないNewtype
未初期化を Option で表す不変条件が不明確ビルダー
不変条件があるのにフィールドを公開する不変条件違反非公開フィールド+検証済みの new()

関連スキル

場面参照先
ドメインモデリングm09-domain
トレイト設計m04-zero-cost
コンストラクターでのエラー処理m06-error-handling
アンチパターンm15-anti-pattern

コメント