LoginSignup
10
11

More than 5 years have passed since last update.

Stream.unfold/2 で無限 FizzBuzz

Last updated at Posted at 2015-08-17

無限リストによるエラトステネスのふるい でも書いたが Stream を使うと Elixir でも遅延評価な無限リストを扱うことができる。その Stream にあるコンストラクタ関数の一つであるところの unfold/2 を使うと、再帰的に処理を行いながらアキュムレータに結果を積んでいく・・・というよくあるパターンを、無限リストとして実装できる。

カッとなって無限に FizzBuzz するストリームを書いてみた。

fizzbuzz = fn
  {true, true}   -> "FizzBuzz"
  {true, false}  -> "Fizz"
  {false, true}  -> "Buzz"
  {false, false} -> nil
end

fst = Stream.unfold(1, fn(n) ->
  res = case fizzbuzz.({rem(n, 3) == 0, rem(n, 5) == 0}) do
    nil -> n
    s   -> s
  end
  {res, n + 1}
end)

fst |> Enum.take(100) |> IO.inspect

一見ただの FizzBuzz だが

fst |> Enum.take(100) |> IO.inspect

ここでストリームは Enum.take/1 に評価されるまで遅延評価されている。take(100) なら 100件を、take(10000) なら 10,000 件をそのとき初めて処理する。何の役にたつかというと、何の役にも立たない。

10
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
11