I have code that looks like:
import qualified Data.Vector as V
import System.Random
import Control.Monad.State.Lazy
nextWeightedRandom :: State (StdGen, V.Vector Int) Int
nextWeightedRandom = do
(g, fs) <- get
let (i, g') = randomR (0, V.length fs - 1) g
put (g', fs)
return (fs V.! i)
weightedRandomList :: (StdGen, V.Vector Int) -> [Int]
weightedRandomList = evalState $ mapM (\_ -> nextWeightedRandom) [1..]
QuickCheck confirms that the values coming out of weightedRandomList are different and have roughly the distribution that I was hoping for (the Vector Int looks like [5, 5, 5, 10], so that nextWeightedRandom spits out 5 with probability 3/4 and 10 with probability 1/4).
I was able to get it working by guessing my way though the types, but I'm very confused --- isn't evalState getting run over a bunch of different copies of the same generator? Why doesn't the list produced look like [5, 5, 5, 5,...]?
Aucun commentaire:
Enregistrer un commentaire