Amy de Buitléir <amy <at> nualeargais.ie> writes: I realised that that approach leads to a small problem for me. I have written a couple of modules with dozens of functions that work with randomness, and they're all in the State monad. I don't want to rewrite them all to be in the IO monad instead, because I think that design approach would be less clean. But I did some more searching, and discovered that if I use newStdGen instead of getStdGen, my original design works just fine. So for posterity, here's another working solution. import "mtl" Control.Monad.State import System.Random -- | Choose an element at random from a list and return the element and its index -- Ex: runState (randomListSelection ['a', 'b', 'c', 'd', 'e']) (mkStdGen 1) randomListSelection :: (RandomGen s) => [a] -> State s (Int, a) randomListSelection xs = do i <- State $ randomR (0,length xs - 1) return (i, xs !! i) chooseCreatur = do g <- newStdGen return (evalState (randomListSelection ["cat", "dog", "lion", "mouse"]) g)