Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

純粋性リフレクション

💡 お知らせ: このドキュメントはAIによって翻訳されています。表現に違和感がある場合は、原文(英語)を参照するか、翻訳にご協力ください。

注意: これは高度な機能であり、エキスパートのみが使用すべきです。

純粋性リフレクション(Purity reflection)を使うと、高階関数が引数として受け取った関数の純粋性を調べられるようになります。

これにより、選択的な遅延評価や並列評価を行う関数を書くことができます。

例えば、以下は Set.count の実装です:

@ParallelWhenPure
pub def count(f: a -> Bool \ ef, s: Set[a]): Int32 \ ef =
    match purityOf(f) {
        case Purity.Pure(g) =>
            if (useParallelEvaluation(s))
                let h = (k, _) -> g(k);
                let Set(t) = s;
                RedBlackTree.parCount(h, t)
            else
                foldLeft((b, k) -> if (f(k)) b + 1 else b, 0, s)
        case Purity.Impure(g) => foldLeft((b, k) -> if (g(k)) b + 1 else b, 0, s)
    }

ここでは purityOf 関数を使って、f の純粋性をリフレクションしています:

  • f が純粋であれば、Set.count はセットの要素に対して並列に評価されます(セットが並列化に見合うだけ十分に大きい場合)。
  • f がエフェクトを持つ場合は、通常の(シングルスレッドの)畳み込みを使用します。

この利点は、f が純粋でありさえすれば、並列性を無償で得られることです。