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