Возможно, вы захотите прикрепить «случайный» тег к вашему вопросу.
Я не знаю о PureScript, и документация кажется новичку скудной, но в кругах Haskell кажется, что довольно распространенная жалоба: функция генерации случайных чисел всегда возвращает одно и то же значение . Применяются обычные анекдоты о случайных числах.
Однако Haskell имеет установленный doctrine относительно генерации случайных чисел. Это необязательно требует ввода-вывода, даже если в Haskell монада ввода-вывода «содержит» генератор случайных чисел.
В Haskell вам потребуется:
import System.Random
import Control.Monad.Random
Проблема заключается в том, что функция с одинаковыми аргументами всегда возвращает один и тот же результат.
Решение состоит в том, что в качестве аргумента функции необходимо включить начальное состояние генератора случайных чисел, а новый обновленное состояние возвращается как часть результата. Это то, что делает Haskell function randomR :: RandomGen g => (a, a) -> g -> (a, g) . Первый аргумент - это выходной диапазон. Если в вашем массиве 100 элементов с индексами от 0 до 99, это будет двойной кортеж: (0,99).
Если у вас есть функция, возвращающая одно случайное значение, вы можете легко создать второе. возвращает произвольное количество значений, например, вот так:
randomRn :: (RandomGen g, Random a) => (a, a) -> Int -> g -> ([a], g)
randomRn range count g0 =
if (count <= 0)
then ([], g0) -- no values and no change
else let (a0, g1) = randomR range g0
(as, gf) = randomRn range (count-1) g1 -- recursive call
in
(a0:as, gf)
Вы можете использовать свою функцию:
main = do
let seed = 4242
g0 = mkStdGen seed -- get a generator
arraySize = 100::Int
range = (0, arraySize-1)
count = 20 -- want "count" random indexes into array
(indexes, gf) = randomRn range count g0
putStrLn $ "Random indexes v1: " ++ show indexes
Вывод программы:
Random indexes v1: [9,56,13,9,38,86,62,18,77,4,66,65,27,33,68,55,94,15,77,45]
Теперь, в зависимости от вкуса, стиля, сложности проблемы, вы можете найти явное присутствие состояния надоедливым и захотеть как-то его скрыть. Для этой цели Haskell использует вариант монады состояний, известный как MonadRandom . Используя такой подход, вы могли бы использовать такой код для определения monadi c action , возвращающего список случайных значений:
iterateMn :: MonadRandom mr => (Int, Int) -> Int -> mr [Int]
iterateMn range count =
if (count <= 0) then
return [] -- no action required
else
do
v1 <- getRandomR range
vs <- iterateMn range (count-1)
return (v1:vs)
По сути, это тот же код, что и выше, за исключением того, что вы не управляете государством явно. action запускается таким образом, используя функцию runRand :
let action = iterateMn range count -- monadic action object
(indexes2, gf2) = runRand action g0 -- go generate indexes
Подробнее здесь: SO_q57890878_r11282404
It кажется, что средство генерации случайных чисел PureScript построено на базе Javascript. В зависимости от того, насколько строгими являются ваши требования, это может быть или не быть достаточно хорошим. Вы можете решить прикусить пулю и внедрить, например, PureScript-версию генератора случайных чисел MRG32k3A . Известно, что его статистические свойства достаточно сильны, а его состояние имеет очень маленький объем памяти и, таким образом, аккуратно адаптируется к функциональным языкам программирования. По-видимому, уже есть несколько реализаций Lisp.