Мне нужно создать случайные данные в Haskell.
Я хочу, чтобы мой код был:
а) воспроизводимый из семян
б) потоки генераторов должны быть неявными
Я в целом понимаю монады и то, как работают случайные генераторы.
Мой подход состоит в том, чтобы пропустить генератор через код, чтобы я мог воспроизвести случайные числа, но хочу скрыть потоки генераторов в монаде.
Я думаю, что Государственная Монада - это хороший подход.
Вот простой код:
type Gen a = State StdGen a
roll :: Gen Int
roll = state $ randomR (1, 6)
roll2 :: Gen Int
roll2 = (+) <$> roll <*> roll
test :: Int -> IO ()
test seed = do
let gen = mkStdGen seed
print (evalState roll gen)
print (evalState roll gen)
print (evalState roll2 gen)
print (evalState roll2 gen)
Я пытаюсь использовать State, чтобы я мог протолкнуть резьбу генератора в State Monad, но результаты броска такие же, как и результаты roll2. Я вижу, что это потому, что я передаю gen в функции несколько раз, поэтому, конечно, он будет выдавать один и тот же результат. Это заставляет меня думать, что мне нужно получить новый генератор от каждой функции. Но затем я вернулся к тому, чтобы пропустить генератор через код, чего я пытаюсь избежать, используя State. Я чувствую, что мне не хватает трюка!
Я тоже исследовал MonadRandom, и это оттолкнуло многопоточность от моего кода, но я не мог понять, как сделать этот подход воспроизводимым.
Я много охотился и много чего пробовал, но, похоже, всегда либо смог скрыть генераторы, либо сделать код воспроизводимым, но не оба одновременно.
Я хочу использовать монаду более специфичную, чем IO.
Я также собираюсь создать серию более сложных функций, которые будут генерировать случайные списки чисел, поэтому мне нужен простой способ, чтобы эти случайные функции зависели друг от друга. Я справился с этим с MonadRandom, но снова я не мог понять, как это можно воспроизвести.
Любая помощь приветствуется.