Я хочу сгенерировать N чисел, используя функцию System.Random.next
. Я реализовал функцию, которая принимает StdGen
и список чисел и возвращает новый генератор и обновленный список чисел:
import System.Random
getRandNum :: StdGen -> [Int] -> (StdGen, [Int])
getRandNum gen nums = (newGen, newNums)
where
(randNum, newGen) = next gen
newNums = nums ++ [randNum]
Затем я могу использовать его следующим образом:
λ: getRandNum (mkStdGen 1) []
(80028 40692,[39336])
Но у меня проблема с выполнением этой функции N раз, чтобы получить список случайных чисел. Как я могу правильно связать это?
Я также попробовал рекурсивный способ — он работает, но я уверен, что это решение далеко не элегантное:
randomnumbers_ :: Int -> StdGen -> (StdGen, [Int])
randomnumbers_ 0 gen = (gen, [])
randomnumbers_ 1 gen = (newGen, [randNum])
where
(randNum, newGen) = next gen
randomnumbers_ n gen = (newGen2, nums ++ nums2)
where
(newGen, nums) = randomnumbers_ 1 gen
(newGen2, nums2) = randomnumbers_ (n - 1) newGen
randomnumbers :: Int -> Int -> [Int]
randomnumbers n seed = snd $ randomnumbers_ n generator
where
generator = mkStdGen seed
Кстати да, я знаю что это можно реализовать с помощью монады State
и знаю как это сделать.
curry
иuncurry
по мере необходимости. как вы упомянули, это то, что делает State Monad. или вручную распаковав кортежи и используя соответствующие значения в цепных или рекурсивных вызовах функций, как показано в ответах. - person Will Ness   schedule 19.03.2021