評価4: 型システムの実践 - 評価基準

評価の目的

この評価では、学生がZigの型システムの実践的な活用能力、特に安全な型変換、オプショナル型の使用、ユニオン型の理解を確認します。型安全性はZigプログラミングの核心です。

学習目標

  • 安全な型変換を実装できる
  • オプショナル型を適切に使用できる
  • ユニオン型とタグ付きユニオンを理解し活用できる
  • 型パラメータを使ったジェネリック関数を作成できる
  • エラーハンドリングと型システムを統合できる

評価項目

1. 型変換ユーティリティ(20点)

項目 配点 評価基準
**安全なキャスト** 6点 6点:範囲チェックを含むsafeCast実装
4点:基本的な動作はするが範囲チェック不完全
2点:型変換のみで安全性なし
0点:動作しない
**文字列パース** 5点 5点:エラー処理を含む完全なparseInteger実装
3点:基本的なパースは動作
0点:動作しない
**整数→文字列** 5点 5点:allocatorを使った正しい実装とメモリ管理
3点:動作するがメモリ管理に問題
0点:動作しない
**浮動小数点→文字列** 4点 4点:精度指定を含む完全な実装
2点:基本的な変換のみ
0点:動作しない

実装チェックポイント:

fn safeCast(comptime T: type, value: i64) ?T {
    const min = std.math.minInt(T);
    const max = std.math.maxInt(T);
    if (value < min or value > max) return null;
    return @intCast(value);
}

fn parseInteger(comptime T: type, str: []const u8) !T {
    return try std.fmt.parseInt(T, str, 10);
}

fn integerToString(allocator: std.mem.Allocator, value: i64) ![]u8 {
    return try std.fmt.allocPrint(allocator, "{}", .{value});
}

2. オプショナル型の活用(20点)

項目 配点 評価基準
**配列検索** 5点 5点:findIndex関数が正しく動作し、見つからない場合nullを返す
3点:基本的な検索は動作
0点:動作しない
**最大値・最小値** 6点 6点:maxValue/minValue両方が空配列でnullを返す
4点:一方のみ正しい
0点:動作しない
**デフォルト値処理** 5点 5点:unwrapOrを使ったデフォルト値設定
3点:基本的な使用のみ
0点:理解不十分
**オプショナルチェーン** 4点 4点:mapOptionalを使った変換処理
2点:限定的な実装
0点:動作しない

評価ポイント:

fn findIndex(comptime T: type, array: []const T, target: T) ?usize {
    for (array, 0..) |item, i| {
        if (item == target) return i;
    }
    return null;
}

fn maxValue(comptime T: type, array: []const T) ?T {
    if (array.len == 0) return null;
    var max = array[0];
    for (array[1..]) |item| {
        if (item > max) max = item;
    }
    return max;
}

3. ユニオン型とタグ付きユニオン(20点)

項目 配点 評価基準
**Result型の定義** 6点 6点:Success/Errorを含む完全なResult型定義
4点:基本的な定義のみ
0点:不完全
**パターンマッチング** 8点 8点:switch文で全てのケースを適切に処理
6点:主要なケースは処理
3点:限定的な処理
0点:理解不十分
**型安全性** 6点 6点:タグとペイロードの組み合わせを正しく使用
4点:基本的な使用のみ
0点:不適切

実装例:

const Result = union(enum) {
    success: i32,
    error_msg: []const u8,

    pub fn isSuccess(self: Result) bool {
        return switch (self) {
            .success => true,
            .error_msg => false,
        };
    }
};

4. ジェネリック関数(20点)

項目 配点 評価基準
**型パラメータ使用** 8点 8点:comptime型パラメータを正しく使用
6点:基本的な使用のみ
3点:理解が浅い
0点:使用できない
**型制約** 6点 6点:適切な型制約とコンパイルエラー
4点:制約はあるが不完全
0点:制約なし
**実装品質** 6点 6点:複数の型で動作し、エッジケースも処理
4点:基本的な型のみ対応
0点:限定的

ボーナス課題の評価

Bonus 1: 高度なオプショナル操作(15点)

配点 評価基準
15点 flatMap、filterOptional、combineなど複数の高度な関数を実装
10点 2-3個の関数を実装
5点 1個のみ
0点 未実装または動作しない

Bonus 2: カスタムアロケータ(20点)

配点 評価基準
20点 メモリプール、アリーナアロケータを実装し、適切に動作
15点 基本的なカスタムアロケータを実装
10点 部分的な実装
0点 動作しない

Bonus 3: 型レベルプログラミング(15点)

配点 評価基準
15点 @typeInfoを使った複雑な型操作を実装
10点 基本的な型情報の取得と使用
5点 限定的な使用
0点 理解不十分

Bonus 4: パフォーマンス比較(20点)

配点 評価基準
20点 詳細なベンチマークと分析レポート
15点 基本的な測定と分析
10点 測定のみ
0点 不完全

評価チェックリスト

マンダトリー要件

  • [ ] Part 1の4つの関数すべてが動作する
  • [ ] safeCastで範囲チェックが実装されている
  • [ ] Part 2のオプショナル型関数が正しくnullを返す
  • [ ] Part 3のユニオン型が適切に定義されている
  • [ ] Part 3でswitch文による網羅的なパターンマッチング
  • [ ] Part 4のジェネリック関数が複数の型で動作する
  • [ ] メモリリークがない
  • [ ] エラー処理が適切
  • [ ] コンパイルエラーなく動作

コード品質

  • [ ] 型注釈が適切
  • [ ] allocatorの使用とdeferによる解放
  • [ ] エラーメッセージがわかりやすい
  • [ ] 変数名が意味を持つ

ボーナス要件

  • [ ] Bonus 1: 複数の高度なオプショナル操作
  • [ ] Bonus 2: カスタムアロケータの実装
  • [ ] Bonus 3: 型レベルプログラミングの活用
  • [ ] Bonus 4: ベンチマークと分析
  • 合格基準

    レベル 点数 説明
    **優秀** 90-100点 型システムを完全に理解し、高度な機能を活用できる
    **良好** 80-89点 基本的な型操作ができ、一部の高度な機能を使用
    **合格** 70-79点 型の基礎を理解し、基本的な実装ができる
    **要再提出** 0-69点 型システムの理解が不十分、復習が必要

    学習の手引き

    効果的な学習方法

  • オプショナル型の理解
- nullの概念と安全な扱い方 - if文とオプショナルのアンラップ - orelseによるデフォルト値設定

  • ユニオン型の活用
- タグ付きユニオンの定義 - switch文による網羅的なパターンマッチング - 型安全性の確保

  • ジェネリックプログラミング
- comptime型パラメータの使用 - 型制約の実装 - 複数の型での動作確認

よくある間違いと対策

間違い1: オプショナルのアンラップ忘れ

// ❌ 間違い
const value: ?i32 = findValue();
print("{}", .{value});  // エラー: オプショナル型

// ✅ 正しい
if (findValue()) |value| {
    print("{}", .{value});
}

間違い2: ユニオン型のタグ不一致

// ❌ 間違い
const result = Result{ .success = 42 };
const msg = result.error_msg;  // パニック!

// ✅ 正しい
switch (result) {
    .success => |val| print("{}", .{val}),
    .error_msg => |msg| print("{s}", .{msg}),
}

時間配分の目安

  • Part 1: 3-4時間
  • Part 2: 3-4時間
  • Part 3: 3-4時間
  • Part 4: 3-4時間
  • ボーナス: 8-12時間
  • 合計: 12-16時間(マンダトリー)、20-28時間(ボーナス込み)

    参考資料

  • Zig Language Reference - Optional Type: https://ziglang.org/documentation/master/#Optional-Type
  • Zig Language Reference - Tagged Union: https://ziglang.org/documentation/master/#Tagged-union
  • Zig Standard Library - mem: https://ziglang.org/documentation/master/std/#std.mem
  • Zig Learn - Chapter 1: https://ziglearn.org/chapter-1/