mercredi 29 avril 2015

Why does this list contain more than one distinct value?

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