diff --git a/AI/SimpleEA.hs b/AI/SimpleEA.hs
--- a/AI/SimpleEA.hs
+++ b/AI/SimpleEA.hs
@@ -29,8 +29,12 @@
 ) where
 
 import Control.Monad.Random
+import System.Random.Mersenne.Pure64
 
+-- | An individual's fitness is simply a number.
 type Fitness = Double
+
+-- | A genome is a list (e.g. a 'String').
 type Genome a = [a]
 
 -- | A fitness functions assigns a fitness score to a genome. The rest of the
@@ -41,14 +45,15 @@
 -- | A selection function is responsible for selection. It takes pairs of
 -- genomes and their fitness and is responsible for returning one or more
 -- individuals.
-type SelectionFunction a = [(Genome a, Fitness)] -> Rand StdGen [Genome a]
+type SelectionFunction a = [(Genome a, Fitness)] -> Rand PureMT [Genome a]
 
 -- | A recombination operator takes two /parent/ genomes and returns two
 -- /children/.
-type RecombinationOp a = (Genome a, Genome a) -> Rand StdGen (Genome a, Genome a)
+type RecombinationOp a = (Genome a, Genome a) -> Rand PureMT (Genome a, Genome a)
 
--- | A mutation operator takes a genome and returns an altered copy of it.
-type MutationOp a        = Genome a -> Rand StdGen (Genome a)
+-- | A mutation operator takes a genome and returns (a possibly altered) copy
+-- of it.
+type MutationOp a = Genome a -> Rand PureMT (Genome a)
 
 -- | Runs the evolutionary algorithm with the given start population. This will
 -- produce an infinite list of generations and 'take' or 'takeWhile' should be
@@ -70,7 +75,7 @@
   SelectionFunction a ->
   RecombinationOp a ->
   MutationOp a ->
-  StdGen ->
+  PureMT ->
   [[(Genome a,Fitness)]]
 runEA startPop fitFun selFun recOp mutOp g =
   let p = zip startPop (map (`fitFun` startPop) startPop)
@@ -82,7 +87,7 @@
   FitnessFunc a ->
   RecombinationOp a ->
   MutationOp a ->
-  Rand StdGen [[(Genome a, Fitness)]]
+  Rand PureMT [[(Genome a, Fitness)]]
 generations !pop selFun fitFun recOp mutOp = do
     -- first, select parents for the new generation
     newGen <- selFun pop
@@ -98,7 +103,7 @@
 
     return $ pop : nextGens
 
-doRecombinations :: [Genome a] -> RecombinationOp a -> Rand StdGen [Genome a]
+doRecombinations :: [Genome a] -> RecombinationOp a -> Rand PureMT [Genome a]
 doRecombinations []      _   = return []
 doRecombinations [_]     _   = error "odd number of parents"
 doRecombinations (a:b:r) rec = do
@@ -115,21 +120,24 @@
 >import AI.SimpleEA
 >import AI.SimpleEA.Utils
 >
+>import System.Random.Mersenne.Pure64
 >import Control.Monad.Random
 >import Data.List
 >import System.Environment (getArgs)
 >import Control.Monad (unless)
 
-The @numOnes@ function will function as our 'FitnessFunc' and simply returns the number of @1@'s
-in the string.
+The @numOnes@ function will function as our 'FitnessFunc' and simply returns
+the number of @1@'s in the string. It ignores the rest of the population (the
+second parameter) since the fitness is not relative to the other individuals in
+the generation.
 
 >numOnes :: FitnessFunc Char
 >numOnes g _ = (fromIntegral . length . filter (=='1')) g
 
 The @select@ function is our 'SelectionFunction'. It uses sigma-scaled, fitness-proportionate
 selection. 'sigmaScale' is defined in 'SimpleEA.Utils'. By first taking the four
-best genomes (by using the @elite@ function) we get elitism, making sure that
-maximum fitness never decreases.
+best genomes (by using the @elite@ function) we make sure that maximum fitness
+never decreases ('elitism').
 
 >select :: SelectionFunction Char
 >select gs = select' (take 4 $ elite gs)
@@ -143,9 +151,9 @@
 >                     let newPop = p1:p2:gs'
 >                     select' newPop
 
-Crossover consists of finding a crossover point along the length of the genomes
-and swapping what comes after between the two genomes. The parameter @p@
-determines the likelihood of crossover taking place.
+Crossover is done by finding a crossover point along the length of the genomes
+and swapping what comes after that point between the two genomes. The parameter
+@p@ determines the likelihood of crossover taking place.
 
 >crossOver :: Double -> RecombinationOp Char
 >crossOver p (g1,g2) = do
@@ -156,7 +164,8 @@
 >           return (take r g1 ++ drop r g2, take r g2 ++ drop r g1)
 >       else return (g1,g2)
 
-Mutation flips a random bit along the length of the genome with probability @p@.
+The mutation operator @mutate@ flips a random bit along the length of the
+genome with probability @p@.
 
 >mutate :: Double -> MutationOp Char
 >mutate p g = do
@@ -179,10 +188,9 @@
 
 >main = do
 >    args <- getArgs
->    g <- newStdGen
->    let (g1,g2) = split g
->    let p = take 100 $ randomGenomes 20 '0' '1' g1
->    let gs = take 101 $ runEA p numOnes select (crossOver 0.75) (mutate 0.01) g2
+>    g <- newPureMT
+>    let (p,g') = runRand (randomGenomes 100 20 '0' '1') g
+>    let gs = take 101 $ runEA p numOnes select (crossOver 0.75) (mutate 0.01) g'
 >    let fs = avgFitnesses gs
 >    let ms = maxFitnesses gs
 >    let ds = stdDeviations gs
diff --git a/AI/SimpleEA/Utils.hs b/AI/SimpleEA/Utils.hs
--- a/AI/SimpleEA/Utils.hs
+++ b/AI/SimpleEA/Utils.hs
@@ -19,9 +19,10 @@
   , getPlottingData
 ) where
 
-import Control.Monad (liftM)
+import Control.Monad (liftM, replicateM)
 import Control.Monad.Random
 import Data.List (genericLength, zip4, sortBy, nub, elemIndices, sort)
+import System.Random.Mersenne.Pure64 (PureMT)
 import AI.SimpleEA
 
 -- |Returns the average fitnesses for a list of generations.
@@ -48,12 +49,12 @@
           mean    = sum p/len
           sqDiffs = map (\n -> (n-mean)**2) p
 
--- |Returns an infinite list of random genomes of length @len@ made of elements
--- in the range @[from,to]@
-randomGenomes :: (Random a, Enum a) => Int -> a -> a -> StdGen -> [Genome a]
-randomGenomes len from to = do
-    l <- randomRs (from,to)
-    return $ nLists len l
+-- |Returns a list of @len@ random genomes who has length @genomeLen@ made of
+-- elements in the range @[from,to]@.
+randomGenomes :: (RandomGen g, Random a, Enum a) => Int -> Int -> a -> a -> Rand g [Genome a]
+randomGenomes len genomeLen from to = do
+    l <- replicateM (len*genomeLen) $ getRandomR (from,to)
+    return $ nLists genomeLen l
     where nLists :: Int -> [a] -> [[a]]
           nLists _ [] = []
           nLists n ls = take n ls : nLists n (drop n ls)
@@ -76,7 +77,7 @@
 -- |Fitness-proportionate selection: select a random item from a list of (item,
 -- score) where each item's chance of being selected is proportional to its
 -- score
-fitPropSelect :: [(a, Fitness)] -> Rand StdGen a
+fitPropSelect :: (RandomGen g) => [(a, Fitness)] -> Rand g a
 fitPropSelect xs = do
     let xs' = zip (map fst xs) (scanl1 (+) $ map snd xs)
     let sumScores = (snd . last) xs'
@@ -84,7 +85,7 @@
     return $ (fst . head . dropWhile ((rand >) . snd)) xs'
 
 -- |Performs tournament selection amoing @size@ individuals and returns the winner
-tournamentSelect :: [(a, Fitness)] -> Int -> Rand StdGen a
+tournamentSelect :: [(a, Fitness)] -> Int -> Rand PureMT a
 tournamentSelect xs size = do
     let l = length xs
     rs <- liftM (take size . nub) $ getRandomRs (0,l-1)
diff --git a/SimpleEA.cabal b/SimpleEA.cabal
--- a/SimpleEA.cabal
+++ b/SimpleEA.cabal
@@ -1,7 +1,7 @@
 name:               SimpleEA
-category:			AI
+category:           AI
 build-type:         Simple
-version:            0.1.1
+version:            0.2
 synopsis:           Simple evolutionary algorithm framework.
 description:        Simple framework for running an evolutionary algorithm by
                     providing selection, recombination, and mutation operators.
@@ -11,15 +11,17 @@
 author:             Erlend Hamberg
 maintainer:         ehamberg@gmail.com
 stability:          experimental
-tested-with:        GHC==7.0.1
+tested-with:        GHC==7.4.1
 homepage:           http://www.github.com/ehamberg/simpleea/
 cabal-version:       >=1.6
 
 
 Library
-    build-depends:      base >=4 && < 5, MonadRandom
-    ghc-options:        -Wall -fno-warn-name-shadowing -fno-warn-orphans
-    exposed-modules:    AI.SimpleEA, AI.SimpleEA.Utils
+    build-depends:   base >=4 && < 5,
+                     MonadRandom,
+                     mersenne-random-pure64 >= 0.2 && < 0.3
+    ghc-options:     -Wall -fno-warn-name-shadowing -fno-warn-orphans
+    exposed-modules: AI.SimpleEA, AI.SimpleEA.Utils
 
 source-repository head
   type:     git
