Skip to content

Instantly share code, notes, and snippets.

@benjamintanweihao
Created January 13, 2015 08:42
Show Gist options
  • Select an option

  • Save benjamintanweihao/b474958832975078f667 to your computer and use it in GitHub Desktop.

Select an option

Save benjamintanweihao/b474958832975078f667 to your computer and use it in GitHub Desktop.
Stream.resource/3 example
defmodule StepGenerator do
use GenServer
defmodule State do
defstruct step: nil, current: nil
end
def start_link(start_from, step) do
GenServer.start_link(__MODULE__, %State{step: step, current: start_from})
end
def next(iterator) do
GenServer.call(iterator, :get_next)
end
def stop(iterator) do
GenServer.call(iterator, :stop)
end
def stream(start_from, step) do
Stream.resource(fn ->
{:ok, gen} = start_link(start_from, step)
gen
end,
fn(gen) ->
result = next(gen)
# NOTE: We could add another condition here to artificially halt the iteration.
case is_number(result) do
true -> {[result], gen}
false -> {:halt, gen}
end
end,
fn(gen) -> stop(gen) end)
end
# Callbacks
def init(state) do
{:ok, state}
end
def handle_call(:get_next, _from, %State{step: step, current: current} = state) do
new_state = %{state | current: current + step}
{:reply, new_state.current, new_state}
end
def handle_call(:stop, from, state) do
GenServer.reply(from, :ok)
{:stop, :normal, state}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment