diff --git a/Control/Monad/Mersenne/Random.hs b/Control/Monad/Mersenne/Random.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Mersenne/Random.hs
@@ -0,0 +1,180 @@
+--------------------------------------------------------------------
+-- |
+-- Module    : Control.Monad.Mersenne.Random
+-- Copyright : (c) Don Stewart 2010
+--
+-- License   : BSD3
+--
+-- Maintainer: Don Stewart <dons@galois.com>
+-- Stability : provisional
+--
+-- A fast random number generator monad.
+--
+
+module Control.Monad.Mersenne.Random (
+
+    -- * Random monad
+    Rand(..),
+    runRandom,
+    evalRandom,
+
+    -- * Efficient generators (Word64 is the primitive getter).
+    getBool,
+    getInt,
+    getWord,
+    getInt64,
+    getWord64,
+    getDouble,
+
+    -- * Internals
+    R(..),
+
+    -- $example
+
+ ) where
+
+import Control.Monad
+import Data.Word
+import Data.Int
+import System.Random.Mersenne.Pure64
+
+
+-- | The state of a random monad, optimized for performance.
+data R a = R !a {-# UNPACK #-}!PureMT
+
+------------------------------------------------------------------------
+
+-- | A basic random monad, for generating random numbers from pure mersenne twisters.
+newtype Rand a = Rand { runRand :: PureMT -> R a }
+
+instance Monad Rand where
+
+    {-# INLINE return #-}
+    return a = Rand $ \s -> R a s
+
+    {-# INLINE (>>=) #-}
+    m >>= k  = Rand $ \s -> case runRand m s of
+                                R a s' -> runRand (k a) s'
+
+    {-# INLINE (>>) #-}
+    m >>  k  = Rand $ \s -> case runRand m s of
+                                R _ s' -> runRand k s'
+
+-- | Run a random computation using the generator @g@, returning the result
+-- and the updated generator.
+runRandom  :: Rand a -> PureMT -> (a, PureMT)
+runRandom  r g = case runRand r g of R x g -> (x, g)
+
+-- | Evaluate a random computation using the mersenne generator @g@.  Note that the
+-- generator @g@ is not returned, so there's no way to recover the
+-- updated version of @g@.
+evalRandom :: Rand a -> PureMT -> a
+evalRandom r g = case runRand r g of R x _ -> x
+
+------------------------------------------------------------------------
+-- Efficient 'get' functions.
+
+getBool     :: Rand Bool
+getBool     = Rand $ \s -> case randomInt s of (w,s') -> R (w < 0) s'
+
+-- | Yield a new 'Int' value from the generator.
+getInt      :: Rand Int
+getInt      = Rand $ \s -> case randomInt s of (w,s') -> R w s'
+
+-- | Yield a new 'Word' value from the generator.
+getWord     :: Rand Word
+getWord     = Rand $ \s -> case randomWord s of (w,s') -> R w s'
+
+-- | Yield a new 'Int64' value from the generator.
+getInt64    :: Rand Int64
+getInt64    = Rand $ \s -> case randomInt64 s of (w,s') -> R w s'
+
+-- | Yield a new 53-bit precise 'Double' value from the generator.
+getDouble   :: Rand Double
+getDouble   = Rand $ \s -> case randomDouble s of (w,s') -> R w s'
+
+-- | Yield a new 'Word64' value from the generator.
+getWord64   :: Rand Word64
+getWord64   = Rand $ \s -> case randomWord64 s of (w,s') -> R w s'
+
+------------------------------------------------------------------------
+-- $example
+--
+-- An example from a user on Stack Overflow -- taking a random walk, and
+-- printing a histogram.
+--
+-- > {-# LANGUAGE BangPatterns #-}
+-- >
+-- > import System.Environment
+-- > import Text.Printf
+-- > import Control.Monad.Mersenne.Random
+-- > import System.Random.Mersenne.Pure64
+-- >
+-- > main :: IO ()
+-- > main = do
+-- >   (size:iters:_) <- fmap (map read) getArgs
+-- >   let start = take size $ repeat 0
+-- >   rnd <- newPureMT
+-- >   let end = flip evalRandom rnd $ mapM (iterateM iters randStep) start
+-- >   putStr . unlines $ histogram "%.2g" end 13
+-- > 
+-- > {-# INLINE iterateM #-}
+-- > iterateM n f x = go n x
+-- >     where
+-- >         go 0 !x = return x
+-- >         go n !x = f x >>= go (n-1)
+-- > 
+-- > randStep :: Double -> Rand Double
+-- > randStep x = do
+-- >     v <- getBool
+-- >     return $! if v then x+1 else x-1
+-- > 
+-- >
+-- > histogram :: String -> [Double] -> Int -> [String]
+-- > histogram _ _ 0 = []
+-- > histogram fmt xs bins =
+-- >     let xmin = minimum xs
+-- >         xmax = maximum xs
+-- >         bsize = (xmax - xmin) / (fromIntegral bins)
+-- >         bs = take bins $ zip [xmin,xmin+bsize..] [xmin+bsize,xmin+2*bsize..]
+-- >         counts :: [Int]
+-- >         counts = let cs = map count bs
+-- >                  in  (init cs) ++ [last cs + (length $ filter (==xmax) xs)]
+-- >     in  map (format (maximum counts)) $ zip bs counts
+-- >   where
+-- >     toD :: (Real b) => b -> Double
+-- >     toD = fromRational . toRational
+-- >     count (xmin, xmax) = length $ filter (\x -> x >= xmin && x < xmax) xs
+-- >     format :: Int -> ((Double,Double), Int) -> String
+-- >     format maxc ((lo,hi), c) = 
+-- >         let cscale = 50.0 / toD maxc
+-- >             hashes = take (round $ (toD c)*cscale) $ repeat '#'
+-- >             label  = let los = printf fmt lo
+-- >                          his = printf fmt hi
+-- >                          l   = los ++ " .. " ++ his
+-- >                          pad = take (20 - (length l)) $ repeat ' '
+-- >                      in  pad ++ l
+-- >         in  label ++ ": " ++ hashes
+-- > 
+--
+-- Compiling this:
+--
+-- > $ ghc -O2 --make B.hs
+--
+-- And running it:
+--
+-- > $ time E 300 5000
+-- >   -194.00 .. -164.46: 
+-- >   -164.46 .. -134.92: #
+-- >   -134.92 .. -105.38: ####
+-- >    -105.38 .. -75.85: ###########
+-- >     -75.85 .. -46.31: #########################
+-- >     -46.31 .. -16.77: ##################################################
+-- >      -16.77 .. 12.77: #################################################
+-- >       12.77 .. 42.31: ###########################################
+-- >       42.31 .. 71.85: ###########################
+-- >      71.85 .. 101.38: ################
+-- >     101.38 .. 130.92: #######
+-- >     130.92 .. 160.46: #####
+-- >     160.46 .. 190.00: #
+-- > ./E 500 3000  0.03s user 0.00s system 96% cpu 0.035 total
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Don Stewart 2010
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Don Stewart nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+import Distribution.Simple
+main = defaultMain
diff --git a/monad-mersenne-random.cabal b/monad-mersenne-random.cabal
new file mode 100644
--- /dev/null
+++ b/monad-mersenne-random.cabal
@@ -0,0 +1,67 @@
+-- monad-mersenne-random.cabal auto-generated by cabal init. For
+-- additional options, see
+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
+-- The name of the package.
+Name:                monad-mersenne-random
+
+-- 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
+
+-- A short (one-line) description of the package.
+Synopsis:            An efficient random generator monad, based on the Mersenne Twister
+
+-- A longer description of the package.
+Description:      Often we need an efficient way to generate high
+    quality pseudo-random numbers in Haskell. We have good generators
+    themselves (for example, the mersenne-random-pure64 package), however, users
+    are often tempted to store the generator in a lazy state monad. This
+    causes performance problems.
+    .
+    This package provides an optimized 'Rand' monad for monadic generation
+    of random numbers from a state, with close attention to performance. You
+    may have results an order of magnitude or more better than using
+    Control.Monad.State to store your generator.
+
+-- URL for the project homepage or repository.
+Homepage:            http://code.haskell.org/~dons/code/monad-mersenne-random
+
+-- The license under which the package is released.
+License:             BSD3
+
+-- The file containing the license text.
+License-file:        LICENSE
+
+-- The package author(s).
+Author:              Don Stewart
+
+-- An email address to which users can send suggestions, bug reports,
+-- and patches.
+Maintainer:          dons@galois.com
+
+-- A copyright notice.
+-- Copyright:           
+
+-- Stability of the pakcage (experimental, provisional, stable...)
+Stability:           Provisional
+
+Category:            Control
+
+Build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or
+-- a README.
+-- Extra-source-files:  
+
+-- Constraint on the version of Cabal needed to build this package.
+Cabal-version:       >=1.2
+
+
+Library
+  -- Modules exported by the library.
+  Exposed-modules:     Control.Monad.Mersenne.Random
+  
+  -- Packages needed in order to build this package.
+  Build-depends:       base > 3 && < 6, mersenne-random-pure64
+  
