diff --git a/Data/Vector/Random/Mersenne.hs b/Data/Vector/Random/Mersenne.hs
--- a/Data/Vector/Random/Mersenne.hs
+++ b/Data/Vector/Random/Mersenne.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE BangPatterns #-}
 --------------------------------------------------------------------
 -- |
 -- Module    : Data.Vector.Random.Mersenne
@@ -12,30 +13,138 @@
 -- Generator for vectors of differen types
 --
 
-module Data.Vector.Random.Mersenne (random) where
+module Data.Vector.Random.Mersenne (
 
-import qualified System.Random.Mersenne     as R
+    -- * Fill a vector with randoms.
+    randoms,
 
+    -- * Class of MT random types
+    PureMTRandom(..)
+
+  ) where
+
+-- import qualified System.Random.Mersenne     as R
+import qualified System.Random.Mersenne.Pure64 as R
+
+
 import qualified Data.Vector.Generic         as G
 import qualified Data.Vector.Generic.Mutable as GM
 
-import Control.Monad.ST
+import qualified Data.Vector.Fusion.Stream         as Stream
+import qualified Data.Vector.Fusion.Stream.Monadic as S
+import qualified Data.Vector.Fusion.Stream.Size    as S
+import Data.Vector.Fusion.Util
 
+-- import System.IO.Unsafe
+-- import GHC.IOBase
+import Data.Bits
+import Data.Int
+import Data.Word
+
 -- | Return a random vector of length @n@, filled with random elements
 -- of type @a@ generated by the mersenne-twister.
 --
 -- E.g. to compute the sum of 100 million random Double values in a vector:
 --
--- > import qualified Data.Vector.Unboxed as U
--- > import System.Random.Mersenne
+-- > import qualified Data.VectorUnboxed as U
+-- > import System.Random.Mersenne.Pure64
 -- > import qualified Data.Vector.Random.Mersenne as G
 -- > 
 -- > main = do
--- >     g <- newMTGen Nothing
--- >     a <- G.random g 10000000 :: IO (U.Vector Double) -- 100 M
+-- >     g <- newPureMT
+-- >     let a = G.random g 10000000 :: U.Vector Double
 -- >     print (U.sum a)
 --
-random :: (R.MTRandom a, G.Vector v a) => R.MTGen -> Int -> IO (v a)
+-- The generator will fuse under stream fusion, so e.g. sum . random g
+-- will allocate no intermediate array.
+--
+
+randoms :: (PureMTRandom a, G.Vector v a) => R.PureMT -> Int -> v a
+randoms g n = G.unstream (randomS g n)
+{-# INLINE randoms #-}
+
+-- A stream of 'n' random numbers.
+--
+randomS :: PureMTRandom a => R.PureMT -> Int -> Stream.Stream a
+{-# INLINE [1] randomS #-}
+randomS g n = S.Stream (return . step) (n, g) (S.Exact (delay_inline max n 0))
+  where
+    {-# INLINE [0] step #-}
+    step (i,g) | i <= 0    = S.Done
+               | otherwise = g `seq` case random g of
+                                (r, g') -> S.Yield r (i-1, g')
+
+------------------------------------------------------------------------
+
+-- | Class of types that we have efficient generators for.
+class PureMTRandom a where
+
+    -- | Given a pure mersenne twister state, yield a new random value,
+    -- and the next state.
+    random :: R.PureMT -> (a, R.PureMT)
+    {-# INLINE random #-}
+
+instance PureMTRandom Double where
+    random = R.randomDouble
+    {-# INLINE random #-}
+
+-- XXX this doesn't inline properly under ghc 6.12
+instance PureMTRandom Float  where
+    random !g = case R.randomDouble g of
+                    (i, g') -> (realToFrac i, g')
+    {-# INLINE random #-}
+
+instance PureMTRandom Word where
+    random = R.randomWord
+    {-# INLINE random #-}
+
+instance PureMTRandom Word8 where
+    random g = case R.randomWord g of (i, g') -> (fromIntegral i, g')
+    {-# INLINE random #-}
+
+instance PureMTRandom Word16 where
+    random g = case R.randomWord g of (i, g') -> (fromIntegral i, g')
+    {-# INLINE random #-}
+
+instance PureMTRandom Word32 where
+    random g = case R.randomWord g of (i, g') -> (fromIntegral i, g')
+    {-# INLINE random #-}
+
+instance PureMTRandom Word64 where
+    random = R.randomWord64
+    {-# INLINE random #-}
+
+instance PureMTRandom Int where
+    random = R.randomInt
+    {-# INLINE random #-}
+
+instance PureMTRandom Int8 where
+    random g = case R.randomInt g of (i, g') -> (fromIntegral i, g')
+    {-# INLINE random #-}
+
+instance PureMTRandom Int16 where
+    random g = case R.randomInt g of (i, g') -> (fromIntegral i, g')
+    {-# INLINE random #-}
+
+instance PureMTRandom Int32 where
+    random g = case R.randomInt g of (i, g') -> (fromIntegral i, g')
+    {-# INLINE random #-}
+
+instance PureMTRandom Int64 where
+    random = R.randomInt64
+    {-# INLINE random #-}
+
+instance PureMTRandom Bool where
+    random g = case R.randomWord g of (i, g') -> (i .&. i /= 0, g')
+    {-# INLINE random #-}
+
+instance PureMTRandom Integer where
+    random g = case R.randomInt g of (i, g') -> (fromIntegral i, g')
+    {-# INLINE random #-}
+
+------------------------------------------------------------------------
+
+{-
 random g n = do
     v  <- GM.new n
     fill v 0
@@ -47,3 +156,26 @@
             GM.unsafeWrite v i x
             fill v (i+1)
         | otherwise = return ()
+-}
+
+------------------------------------------------------------------------
+
+{-
+-- A stream of random 'n' random numbers.
+--
+randomS :: (R.MTRandom a) => R.PureMT -> Int -> Stream.Stream a
+{-# INLINE [1] randomS #-}
+randomS g n = S.Stream (return . step) n (S.Exact (delay_inline max n 0))
+  where
+    {-# INLINE [0] step #-}
+    step i | i <= 0    = S.Done
+           | otherwise =
+               case unsafeDupablePerformIO (R.random' i g) of
+                    r -> S.Yield r (i-1)
+
+
+random' :: R.MTRandom a => Int -> R.PureMT -> IO a
+{-# NOINLINE random' #-}
+random' _ gen = R.random gen
+
+-}
diff --git a/tests/test.hs b/tests/test.hs
--- a/tests/test.hs
+++ b/tests/test.hs
@@ -1,10 +1,11 @@
 
 import qualified Data.Vector.Unboxed as U
-import System.Random.Mersenne
+import System.Random.Mersenne.Pure64
 import qualified Data.Vector.Random.Mersenne as G
+import Data.Int
 
 main = do
-    g <- newMTGen Nothing
-    a <- G.random g 10000000 :: IO (U.Vector Double) -- 100 M
-    print (U.sum a)
-
+    g <- newPureMT
+--     let a = U.map realToFrac (G.randoms g 10000000 :: U.Vector Double) :: U.Vector Float -- 100 M
+    let a = G.randoms g 10000000 -- :: U.Vector Int8 -- 100 M
+    print (U.and a)
diff --git a/vector-random.cabal b/vector-random.cabal
--- a/vector-random.cabal
+++ b/vector-random.cabal
@@ -7,7 +7,7 @@
 -- The package version. See the Haskell package versioning policy
 -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
 -- standards guiding when and how versions should be incremented.
-Version:             0.1
+Version:             0.2
 
 -- A short (one-line) description of the package.
 Synopsis:            Generate vectors filled with high quality pseudorandom numbers
@@ -57,6 +57,10 @@
   -- Packages needed in order to build this package.
   Build-depends:       
     base <= 5,
-    mersenne-random,
+    mersenne-random-pure64,
     vector >= 0.5
+
+  if impl(ghc<6.13)
+    Ghc-Options: -finline-if-enough-args -fno-method-sharing
   
+  GHC-options: -O2
