LoginSignup
4
4

More than 5 years have passed since last update.

ズンドコキヨシ.ex by ストリーム without `Stream`

Posted at

はじめに

もう既に何番煎じか(もうすぐ3桁?)て感じですが、敢えてもう1本上げてみる。
夕べ書いた ズンドコキヨシ.jl with IterationElixir に翻訳してみた。

実装結果

zundoko.ex
# zundoko.ex

defmodule Zundoko do
  def stream do
    &stream(0, &1, &2)
  end

  defp stream(_, {:halt, acc}, _fun), do: {:halted, acc}
  defp stream(v, {:suspend, acc}, fun), do: {:suspended, acc, &stream(v, &1, fun)}
  defp stream(:done, {:cont, acc}, _fun), do: {:done, acc}
  defp stream(5, {:cont, acc}, fun), do:
    stream(:done, fun.("キ・ヨ・シ!", acc), fun)
  defp stream(4, {:cont, acc}, fun), do: 
    stream(Enum.random([{4, "ズン"}, {5, "ドコ"}]), {:cont, acc}, fun)
  defp stream(n, {:cont, acc}, fun) when n < 4, do: 
    stream(Enum.random([{n + 1, "ズン"}, {0, "ドコ"}]), {:cont, acc}, fun)
  defp stream({n, zd}, {:cont, acc}, fun), do: 
    stream(n, fun.(zd, acc), fun)

  def run do
    stream |> Enum.join |> IO.puts
  end
end

Zundoko.run
# => ズンドコズンズンズンドコドコドコズンドコドコズンズンズンズンズンズンズンズンドコキ・ヨ・シ!

ポイントは、「Stream モジュールを使わないストリームの実装」。
(詳しくは 私の過去記事 等参照)
Zundoko.stream の定義に Enum.random 以外の標準ライブラリ関数を使用していません!

ズンドコキヨシ.jl with Iteration と同様、処理本体は Stream(として扱われる関数)として返ってくるので、リストで取得したければ、例えば
Zundoko.stream |> Enum.to_list
とすれば ["ドコ", "ズン", "ドコ", "ズン", "ズン", "ズン", "ズン", "ズン",
"ドコ", "キ・ヨ・シ!"]
といったリストが得られます。

まとめじゃないけれど

ストリーム(無限リスト)やイテレータの定義方法が似ているなら他言語でも同じような感じで実装出来るのではないかと。

4
4
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
4
4