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によって翻訳されています。表現に違和感がある場合は、原文(英語)を参照するか、翻訳にご協力ください。

Flix はほとんどの場面で先行評価(Eager evaluation)を用いますが、lazy キーワードを使うことで、適切な場面でプログラマが遅延評価(Lazy evaluation)を選択できるようになっています:

let x: Lazy[Int32] = lazy (1 + 2);

この式は、強制(force) されるまで評価されません:

let y: Int32 = force x;

注意: lazy 構文に与える式は純粋でなければなりません。

注意: すでに評価済みの遅延値を force しても、再度評価されることはありません。

遅延データ構造

遅延評価を利用すると、使用されるのに合わせて評価される遅延データ構造(Lazy data structure)を作ることができます。これにより、無限のデータ構造を作ることさえ可能になります。

例えば次に示すのは、1 ずつ増えていく整数の無限長ストリームを実装したデータ構造です:

mod IntStream {

    enum IntStream { case SCons(Int32, Lazy[IntStream]) }

    pub def from(x: Int32): IntStream =
        IntStream.SCons(x, lazy from(x + 1))
}

これをもとに、maptake といった関数を実装できます:

    pub def take(n: Int32, s: IntStream): List[Int32] =
        match n {
            case 0 => Nil
            case _ => match s {
                case SCons(h, t) => h :: take(n - 1, force t)
            }
        }

    pub def map(f: Int32 -> Int32, s: IntStream): IntStream =
        match s {
            case SCons(h, t) => IntStream.SCons(f(h), lazy map(f, force t))
        }

例えば:

IntStream.from(42) |> IntStream.map(x -> x + 10) |> IntStream.take(10)

は次を返します:

52 :: 53 :: 54 :: 55 :: 56 :: 57 :: 58 :: 59 :: 60 :: 61 :: Nil

Flix は、この機能やそれ以上の機能をすでに実装済みの DelayListDelayMap というデータ構造を提供しています:

DelayList.from(42) |> DelayList.map(x -> x + 10) |> DelayList.take(10)