Эликсир - рандомизированные числа в агенте

Я пытаюсь реализовать Агент, который ведет себя как кубик:

defmodule Dice do
  @on_load :seed_generator

  def start_link(opts \\ []) do
    Agent.start_link(fn -> [] end, name: __MODULE__)
  end

  def roll(n, val) do
    Agent.cast(__MODULE__, fn(_) ->
      Stream.repeatedly(fn -> :random.uniform(val) end)
      |> Enum.take(n)
    end)
  end

  def seed_generator do
    :random.seed(:erlang.now)
    :ok
  end
end

Однако сгенерированные числа одинаковы, каждый раз, когда я перезапускаю iex. Что я делаю не так? Не работает ли семя, потому что вызов :random.uniform находится внутри Агента? Или что-то связанное с Stream может быть.

Ответ 1

Функция seed_generator вызывается в другом процессе, чем тот, который будет использоваться вашим Agent. На самом деле этот процесс даже не существует в момент загрузки этого кода. Попробуйте посеять генератор при запуске Agent:

defmodule Dice do
  def start_link(opts \\ []) do
    Agent.start_link(fn -> :random.seed(:erlang.now) end, name: __MODULE__)
  end

  def roll(n, val) do
    Agent.get(__MODULE__, fn(_) ->
      Stream.repeatedly(fn -> :random.uniform(val) end)
      |> Enum.take(n)
    end)
  end
end