Próbuję zaimplementować środek, który zachowuje się jak kostki:Elixir - Randomizowane numery w Agenta
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
Jednak wygenerowane numery są takie same, za każdym razem, gdy ponownie uruchomić iex. Co robię źle? Czy materiał siewny nie działa, ponieważ wywołanie :random.uniform
znajduje się wewnątrz agenta? Lub może coś związanego z Stream
.
wydaje się działać, to zrobił: 'Agent.start_link (FN ->: random.seed (: erlang.now); [] koniec, nazwa: __MODULE __)' aby zachować pustą listę jako stan domyślny. Dziękuję Ci. – Kernael
W każdym razie ignorujesz ten stan w funkcji "roll", więc nie sądzę, żeby to miało znaczenie. Twój aktualny stan to słownik procesu, w którym jest przechowywany stan generatora losowego. –
Zamiast funkcji erlang.now(), funkcja os.timestamp() może być również dobra: http://www.erlang.org/doc/man/os.html#timestamp-0 Ponieważ erlang.now() może przynieść trochę problemów. – h4cc