
I would like to point out the importance of Cale Gibbard's MonadRandom, beyond what is currently mentioned on its wiki page: http://www.haskell.org/haskellwiki/New_monads/MonadRandom This monad makes it possible to write functions that use randomness without having to specify in advance whether the source of randomness will be a pure pseudorandom number generator, as in System.Random, or physical randomness via the IO monad, such as your operating system's source of physical randomness, or random.org, or a hardware random generator. Before use of MonadRandom becomes widespread - and I think it ought to - I would like to suggest a change to the interface. (I mentioned this once to Cale on #haskell, but I didn't say what change I meant.) Currently, the members of the MonadRandom class mimic the members of the Random class in System.Random. I think it would be better if instead they mimicked the members of RandomGen. Like this: \begin{code} class (Monad m) => MonadRandom m where nextR :: m Int splitR :: m (m ()) rangeR :: m (Int, Int) getR :: (forall g . RandomGen g => g -> a) -> m a \end{code} The extra function getR provides access not only to the member functions of Random, but to any function that generates random variables of any type. You would use getR random, getR $ randomR (a, b), etc. instead of getRandom, getRandomR (a, b), etc. Provide a default method for getR as follows: \begin{code} getR f = do r <- nextR (lo, hi) <- rangeR return $ f $ TrivialGen r lo hi data TrivialGen = TrivialGen Int Int Int instance RandomGen TrivialGen where next (TrivialGen r _ _) = r genRange (TrivialGen _ lo hi) = (lo, hi) split _ = undefined \end{code} We would use the default method of getR for MonadRandom instances of things like DevRandom, DevURandom, RandomDotOrg, etc. For the Rand and RandT instances we provide explicit methods: \begin{code} -- For RandT: getR f = RandT $ gets f --For Rand: getR =Rand $ getR f \end{code} I think this is better for several reasons: o We anyway need getR for general random variables o We could lose precision getting other random variables via getRandom in the case where genRange /= (minBound, maxBound) o I think it is a better semantic fit Regards, Yitz