diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -3,3 +3,9 @@
 ## 0.1.0.0  -- 2016-08-19
 
 * First version. Released on an unsuspecting world.
+
+## 0.1.1.0  -- 2016-08-26
+
+* Exposes composeProcess for quickly composing StochProcesses.
+* Un-reinvents the State monad.
+* Adds gamma and beta distributions.
diff --git a/src/Data/Stochastic.hs b/src/Data/Stochastic.hs
--- a/src/Data/Stochastic.hs
+++ b/src/Data/Stochastic.hs
@@ -18,11 +18,15 @@
 
 module Data.Stochastic (
   -- * Constructing a Sample
-  certain
-, uniform
+  mkSample
+, certain
+, discreteUniform
 , discrete
 , bernoulli
 , normal
+, uniform
+, gamma
+, beta
   -- * Sampling from a Sample
 , sample
 , sample_
@@ -31,10 +35,15 @@
 , sampleIO_
 , sampleION
   -- * Constructing a StochProcess
+, toProcess
 , certainProcess
-, uniformProcess
+, discreteUniformProcess
 , discreteProcess
 , normalProcess
+, uniformProcess
+, gammaProcess
+, betaProcess
+, composeProcess
   -- * Running a StochProcess
 , runProcess
 , runProcess_
@@ -51,6 +60,7 @@
 , module Data.Stochastic.Internal
 ) where
 
+import Control.Monad.State
 import Control.Monad.Trans
 import Control.Monad.Writer
 
@@ -124,32 +134,42 @@
 -- | 'StochProcess' sample for a normal distribution that records
 -- the value sampled from the normal distribution.
 normalProcess :: Mean -> StDev -> StochProcess 
-normalProcess mean std = do
-    sample <- lift $ normal mean std
-    tell $ S.singleton sample
-    return sample
+normalProcess mean std = toProcess $ normal mean std
 
--- | 'StochProcess' sample for a distribution over 'Double's that always
+-- | 'StochProcess' for a distribution over 'Double's that always
 -- returns the same value when sampled, and records that value.
 certainProcess :: Double -> StochProcess 
-certainProcess a = do
-    sample <- lift $ certain a
-    tell $ S.singleton sample
-    return sample
+certainProcess a = toProcess $ certain a
 
--- | 'StochProcess' sample for a discrete distribution over 'Double's
+-- | 'StochProcess' for a discrete distribution over 'Double's
 -- that records the value sampled from the normal distribution.
 discreteProcess :: [(Double, Double)] -> StochProcess 
-discreteProcess a = do
-    sample <- lift $ discrete a
-    tell $ S.singleton sample
-    return sample
+discreteProcess a = toProcess $ discrete a
 
--- | 'StochProcess' sample for a uniform distribution over 'Double's
--- that records the value sampled from it.
-uniformProcess :: [Double] -> StochProcess
-uniformProcess l = do
-    sample <- lift $ uniform l
+-- | 'StochProcess' for a discrete uniform distribution 
+-- over 'Double's that records the value sampled from it.
+discreteUniformProcess :: [Double] -> StochProcess
+discreteUniformProcess l = toProcess $ discreteUniform l
+
+-- | 'StochProcess' for a discrete uniform distribution 
+-- over 'Double's that records the value sampled from it.
+uniformProcess :: StochProcess
+uniformProcess = toProcess uniform
+
+-- | 'StochProcess' for a gamma distribution with
+-- provided shape and scale parameters.
+gammaProcess :: Double -> Double -> StochProcess
+gammaProcess a b = toProcess $ gamma a b
+
+-- | 'StochProcess' for a beta distribution.
+betaProcess :: Double -> Double -> StochProcess
+betaProcess a b = toProcess $ beta a b
+
+-- | Function to create a 'StochProcess' out of a provided
+-- 'Sample' over 'Double's.
+toProcess :: Sample StdGen Distribution Double -> StochProcess
+toProcess s = do
+    sample <- lift s
     tell $ S.singleton sample
     return sample
 
@@ -171,16 +191,39 @@
 discrete [] = error "do not construct empty discrete distributions"
 discrete l = mkSample $ Discrete l
 
--- | 'Sample' for a uniform distribution
+-- | 'Sample' for a discrete uniform distribution
 -- given a list of provided values.
-uniform :: (RandomGen g) => [a] -> Sample g Distribution a
-uniform l = mkSample $ Uniform l
+discreteUniform :: (RandomGen g) => [a] -> Sample g Distribution a
+discreteUniform l = mkSample $ DiscreteUniform l
 
+-- | 'Sample' for a continuous uniform distribution
+-- with support [0, 1].
+uniform :: (RandomGen g) => Sample g Distribution Double
+uniform = mkSample Uniform
+
 -- | 'Sample' for a distribution where we always sample
 -- the same value.
 certain :: (RandomGen g, Sampleable d) => a -> Sample g d a
 certain = mkSample . certainDist
 
+-- | 'Sample' for a gamma distribution given shape parameter
+-- and scale parameter.
+gamma :: RandomGen g
+      => Double 
+      -- ^ The shape parameter.
+      -> Double 
+      -- ^ The scale parameter.
+      -> Sample g Distribution Double
+gamma a b = if a <= 0 || b <= 0 
+            then error "cannot construct gamma dist with <=0 params"
+            else mkSample $ Gamma a b
+
+-- | 'Sample' for a beta distribution.
+beta :: RandomGen g => Double -> Double -> Sample g Distribution Double
+beta a b = if a <= 0 || b <= 0 
+            then error "cannot construct gamma dist with <=0 params"
+            else mkSample $ Beta a b
+
 -- | Get one sample of type a from the 'Sample' along with
 -- a new 'StdGen'.
 --
@@ -188,7 +231,7 @@
 -- 'RandomGen' because when we sample from normal
 -- distributions, we consume one extra 'RandomGen'.
 sample :: (RandomGen g, Sampleable d) => Sample g d a -> g -> (a, g)
-sample s g = let (dist, g') = runSample s g
+sample s g = let (dist, g') = runState (runSample s) g
                  (a, g'') = sampleFrom dist g'
              in (a, snd $ next g'')
 
@@ -223,4 +266,4 @@
 -- | Function to make a 'Sample' out of a provided
 -- 'Distribution'.
 mkSample :: (RandomGen g, Sampleable d) => d a -> Sample g d a
-mkSample d = Sample $ \g -> (d, snd $ next g)
+mkSample d = Sample $ return d
diff --git a/src/Data/Stochastic/Internal.hs b/src/Data/Stochastic/Internal.hs
--- a/src/Data/Stochastic/Internal.hs
+++ b/src/Data/Stochastic/Internal.hs
@@ -8,21 +8,40 @@
 -}
 module Data.Stochastic.Internal (
   boxMuller
-, decentRandom
+, closedRnd
+, openRnd
+, closedOpenRnd
+, openClosedRnd
 ) where
 
 import System.Random
 
-import Numeric.MathFunctions.Constants
-
 -- | Function to convert values sampled from uniform distribution
 -- to a value sampled from a standard normal distribution.
 boxMuller :: (Floating a) => a -> a -> a
 boxMuller u1 u2 = cos (2 * pi * u2) * (sqrt $ (-2) * (log u1))
 
--- | Randoms that aren't too small or equal to 1.
-decentRandom :: (RandomGen g) => g -> (Double, g)
-decentRandom gen = let (sampled, newG) = randomR (0, 1.0) gen
-                   in if sampled <= m_epsilon || sampled == 1
-                      then decentRandom newG
-                      else (sampled, newG)
+-- | Randoms in the interval [0, 1]
+closedRnd :: (RandomGen g) => g -> (Double, g)
+closedRnd gen = randomR (0, 1.0) gen
+
+-- | Randoms in the interval (0, 1)
+openRnd :: (RandomGen g) => g -> (Double, g)
+openRnd gen = let (a, g) = closedRnd gen
+                   in if a == 0 || a == 1
+                      then openRnd g
+                      else (a, g)
+                      
+-- | Randoms in the interval [0, 1)
+closedOpenRnd :: (RandomGen g) => g -> (Double, g)
+closedOpenRnd gen = let (a, g) = closedRnd gen
+                    in if a == 1
+                       then closedOpenRnd g
+                       else (a, g)
+                      
+-- | Randoms in the interval (0, 1]
+openClosedRnd :: (RandomGen g) => g -> (Double, g)
+openClosedRnd gen = let (a, g) = closedRnd gen
+                   in if a == 0
+                      then openClosedRnd g
+                      else (a, g)
diff --git a/src/Data/Stochastic/Types.hs b/src/Data/Stochastic/Types.hs
--- a/src/Data/Stochastic/Types.hs
+++ b/src/Data/Stochastic/Types.hs
@@ -27,9 +27,11 @@
 , Sampler (..)
 , Mean (..)
 , StDev (..)
+, marsagliaTsang
 ) where
 
 import Control.Monad
+import Control.Monad.State
 import Control.Monad.Writer
 
 import Data.Stochastic.Internal
@@ -46,8 +48,14 @@
     Normal :: Mean -> StDev -> Distribution Double
     Bernoulli :: Double -> Distribution Bool
     Discrete :: [(a, Double)] -> Distribution a
-    Uniform :: [a] -> Distribution a
+    DiscreteUniform :: [a] -> Distribution a
+    Uniform :: Distribution Double
     Certain :: a -> Distribution a
+    Gamma :: Double -> Double -> Distribution Double
+    -- ^ Gamma distribution, where the first parameter is the
+    -- shape parameter alpha, and the second parameter is the
+    -- scale parameter beta.
+    Beta :: Double -> Double -> Distribution Double
 
 -- | Class of types from which samples can be obtained.
 class Sampleable d where
@@ -65,15 +73,17 @@
     sampleFrom da g
         = case da of
             Normal mean stdev 
-                -> let (a, g')   = decentRandom g 
-                       (a', g'') = decentRandom g'
+                -> let (a, g')   = closedRnd g 
+                       (a', g'') = closedRnd g'
                        s = (stdev * (boxMuller a a')) + mean
                    in (s, g')
             Bernoulli prob    
-                -> let (a, g') = decentRandom g
+                -> let (a, g') = closedRnd g
                    in (a <= prob, g')
+            Discrete []
+                -> error "cannot sample from empty discrete distribution"
             Discrete l        
-                -> let (a, g') = decentRandom g
+                -> let (a, g') = closedRnd g
                    in (scan a l, g')
                    where scan lim [] = 
                              if lim <= 0 then error $ "not normalized discrete dist"
@@ -81,28 +91,60 @@
                          scan lim (x:xs) = 
                              if lim <= snd x then fst x 
                              else scan (lim - snd x) xs
-            Uniform l
-                -> let (a, g') = decentRandom g
+            DiscreteUniform []
+                -> error "cannot sample from empty discrete distribution"
+            DiscreteUniform l
+                -> let (a, g') = closedRnd g
                        prob = 1 / (fromIntegral $ length l)
                    in (l !! (floor $ a / prob), g')
+            Uniform
+                -> closedRnd g
+            Gamma alpha beta
+                -> if alpha <= 0 || beta <= 0 then error "alpha and beta parameter cannot be less than or equal to zero in beta distribution"
+                   else if alpha > 0 && alpha < 1 then
+                        let (a, g') = sampleFrom (Gamma (alpha + 1) beta) g
+                            (uni, g'') = openRnd g'
+                        in (a * (uni ** (1/alpha)), g'')
+                   else let d = alpha - (1/3)
+                            c = 1 / sqrt (9 * d)
+                            (m, g') =  marsagliaTsang d c g
+                        in (m * beta, g')
+            Beta alpha beta
+                -> let (x, g') = sampleFrom (Gamma alpha 1) g
+                       (y, g'') = sampleFrom (Gamma beta 1) g'
+                   in (x / (x + y), g'')
             Certain val       
-                -> (val, snd $ decentRandom g) 
+                -> (val, snd $ openRnd g) 
                 -- Seemingly unnecessary, but important to obey the monad laws to always produce the same RandomGen each time we sample.
     certainDist = Certain
 
+-- | Marsaglia and Tsang's rejection method
+-- for generating Gamma variates with parameters
+-- alpha and 1, where 1 is the scale parameter,
+-- given d and c.
+marsagliaTsang :: (RandomGen g) => Double -> Double -> g -> (Double, g)
+marsagliaTsang d c g =
+    let (norm, g') = sampleFrom (Normal 0 1) g
+        (uni, g'') = sampleFrom Uniform g'
+        v = (1 + (c * norm)) ** 3
+    in if norm > ((-1)/c) && 
+          log uni < ((norm ** 2)/2 + d - (d * v) + (d * log v))
+       then (d * v, g'')
+       else marsagliaTsang d c g''
+
 -- | Show instance for 'Distribution's.
 instance (Show a) => Show (Distribution a) where
     show da = case da of
         Normal mean stdev -> "Normal " ++ show mean ++ " " ++ show stdev
         Bernoulli prob -> "Bernoulli " ++ show prob
         Discrete l -> "Discrete " ++ show l
-        Uniform l -> "Uniform " ++ show l       
+        DiscreteUniform l -> "DiscreteUniform " ++ show l       
         Certain val -> "Certain " ++ show val
 
 -- | 'Sample' monad containing a random number generator plus a type from which
 -- we can sample values of type a
 newtype Sample g d a
-    = Sample { runSample :: (RandomGen g, Sampleable d) => g -> (d a, g) }
+    = Sample { runSample :: (RandomGen g, Sampleable d) => State g (d a) }
 
 -- | Monad that represents a stochastic process.
 -- It allows us to record numeric values as we sample.
@@ -111,11 +153,16 @@
 
 -- | Monad instance for Sample.
 instance (RandomGen g, Sampleable d) => Monad (Sample g d) where
-    return x = Sample $ \g -> (certainDist x, snd $ next g)
-    (>>=) ma f = Sample $ \g -> 
-                     let (dist, g') = runSample ma g
-                         (a, g'') = sampleFrom dist g'
-                     in runSample (f a) g''
+    return x = Sample $ do
+                modify (snd . next)
+                return $ certainDist x
+
+    (>>=) ma f = Sample $ do
+                     modify (snd . next)
+                     dist <- runSample ma
+                     g <- get
+                     let a = fst $ sampleFrom dist g
+                     runSample (f a)
 
 -- | Trivial 'Functor' instance for 'Sample' 'StdGen' 'Distribution'.
 instance (RandomGen g, Sampleable s) => Functor (Sample g s) where
diff --git a/stochastic.cabal b/stochastic.cabal
--- a/stochastic.cabal
+++ b/stochastic.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             0.1.0.0
+version:             0.1.1.0
 
 -- A short (one-line) description of the package.
 synopsis:            Monadic composition of probabilistic functions and sampling.
@@ -22,7 +22,7 @@
                      can then be sampled from to generate datapoints.
 
 -- URL for the project homepage or repository.
-homepage:            http://kevinl.io/posts/2016-08-17-sampling-monad.html
+homepage:            http://kevinl.io/posts/2016-08-24-sampling-monad.html
 
 -- The license under which the package is released.
 license:             GPL-3
@@ -55,7 +55,7 @@
 library
   -- Modules exported by the library.
   exposed-modules:     Data.Stochastic
-                       -- Data.Sample.Chart
+                       -- Data.Stochastic.Chart
                        Data.Stochastic.Types
                        Data.Stochastic.Internal
   
@@ -71,7 +71,6 @@
                        -- Chart-cairo >=1.8 && <1.9,
                        containers >= 0.5 && <0.6,
                        random >=1.1 && <2,
-                       math-functions >=0.2 && <0.3,
                        mtl >=2.2 && <2.3
   
   -- Directories containing source files.
@@ -118,7 +117,7 @@
   -- | Options to pass to ghc
   ghc-options:         -O2
                        -threaded
-                       "-with-rtsopts=-N -pa -s -h -i0.1"
+                       -- "-with-rtsopts=-N -pa -s -h -i0.1"
 test-suite normal10
   type:                exitcode-stdio-1.0
   hs-source-dirs:      test
@@ -128,7 +127,7 @@
   -- | Options to pass to ghc
   ghc-options:         -O2
                        -threaded
-                       "-with-rtsopts=-N -pa -s -h -i0.1"
+                       -- "-with-rtsopts=-N -pa -s -h -i0.1"
 
 test-suite chart
   type:                exitcode-stdio-1.0
@@ -163,7 +162,7 @@
   type:                exitcode-stdio-1.0
   hs-source-dirs:      test
   main-is:             MontyHall.hs
-  build-depends:       base, stochastic, containers, random
+  build-depends:       base, stochastic, containers, random, mtl
   default-language:    Haskell2010
   -- | Options to pass to ghc
   ghc-options:         -O2
@@ -178,3 +177,10 @@
   -- | Options to pass to ghc
   ghc-options:         -O2
                        -threaded
+
+test-suite beta
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Beta.hs
+  build-depends:       base, stochastic, random, Chart-cairo, Chart, containers, mtl
+  default-language:    Haskell2010
diff --git a/test/Beta.hs b/test/Beta.hs
new file mode 100644
--- /dev/null
+++ b/test/Beta.hs
@@ -0,0 +1,36 @@
+import Control.Monad.Trans
+
+import Data.Foldable
+import Data.Stochastic
+import Data.Stochastic.Types
+import Data.Stochastic.Internal
+import Data.Stochastic.Chart
+
+import qualified Data.Sequence as S
+
+import System.Random
+import Graphics.Rendering.Chart.Backend.Cairo
+import Graphics.Rendering.Chart.Easy
+
+beta1 :: Sampler Double
+beta1 = beta 0.5 0.5
+
+beta2 :: Sampler Double
+beta2 = beta 0.5 2
+
+gamma1 :: Sampler Double
+gamma1 = gamma 3 2
+
+gamma2 :: Sampler Double
+gamma2 = gamma 3 0.5
+
+main = do
+    gen <- newStdGen
+    let betas1 = sampleN 100000 beta1 gen
+    let betas2 = sampleN 100000 beta2 gen
+    let gammas1 = sampleN 100000 gamma1 gen
+    let gammas2 = sampleN 100000 gamma2 gen
+    renderableToFile def "charts/beta1.png" $ toRenderable $ histogram "Beta1" $ toList betas1
+    renderableToFile def "charts/beta2.png" $ toRenderable $ histogram "Beta2" $ toList betas2
+    renderableToFile def "charts/gamma1.png" $ toRenderable $ histogram "Gamma1" $ toList gammas1
+    renderableToFile def "charts/gamma2.png" $ toRenderable $ histogram "Gamma2" $ toList gammas2
diff --git a/test/ChartTest.hs b/test/ChartTest.hs
--- a/test/ChartTest.hs
+++ b/test/ChartTest.hs
@@ -2,10 +2,10 @@
 
 import Control.Monad.Trans
 
-import Data.Sample
-import Data.Sample.Types
-import Data.Sample.Lib
-import Data.Sample.Chart
+import Data.Stochastic
+import Data.Stochastic.Types
+import Data.Stochastic.Internal
+import Data.Stochastic.Chart
 
 import qualified Data.Sequence as S
 
diff --git a/test/ContrivedGambler.hs b/test/ContrivedGambler.hs
--- a/test/ContrivedGambler.hs
+++ b/test/ContrivedGambler.hs
@@ -1,9 +1,9 @@
 import Data.Foldable
 
-import Data.Sample
-import Data.Sample.Lib
-import Data.Sample.Types
-import Data.Sample.Chart
+import Data.Stochastic
+import Data.Stochastic.Internal
+import Data.Stochastic.Types
+import Data.Stochastic.Chart
 
 import qualified Data.Sequence as S
 
diff --git a/test/CoolCharts.hs b/test/CoolCharts.hs
--- a/test/CoolCharts.hs
+++ b/test/CoolCharts.hs
@@ -1,9 +1,9 @@
 import Control.Monad.Trans
 
-import Data.Sample
-import Data.Sample.Types
-import Data.Sample.Lib
-import Data.Sample.Chart
+import Data.Stochastic
+import Data.Stochastic.Types
+import Data.Stochastic.Internal
+import Data.Stochastic.Chart
 
 import qualified Data.Sequence as S
 
@@ -30,5 +30,5 @@
 
 main = do
     gen <- newStdGen
-    let a = runProcess_ normal1 gen
-    toFile def "chart.png" $ testChart $ S.singleton a
+    let a = runProcessN 10 normal1 gen
+    toFile def "chart.png" $ testChart $ a
diff --git a/test/MonadLaws.hs b/test/MonadLaws.hs
--- a/test/MonadLaws.hs
+++ b/test/MonadLaws.hs
@@ -1,6 +1,6 @@
-import Data.Sample
-import Data.Sample.Lib
-import Data.Sample.Types
+import Data.Stochastic
+import Data.Stochastic.Internal
+import Data.Stochastic.Types
 
 import System.Random
 import System.Exit
diff --git a/test/MontyHall.hs b/test/MontyHall.hs
--- a/test/MontyHall.hs
+++ b/test/MontyHall.hs
@@ -1,7 +1,9 @@
-import Data.Sample
-import Data.Sample.Lib
-import Data.Sample.Types
+import Control.Monad.State
 
+import Data.Stochastic
+import Data.Stochastic.Internal
+import Data.Stochastic.Types
+
 import qualified Data.Sequence as S
 
 import System.Random
@@ -13,7 +15,7 @@
 doorInit n = uniform $ Car : (take (n-1) $ repeat Goat)
 
 removeDoor :: Prize -> Sampler Prize -> Sampler Prize
-removeDoor b sa = let (da, g) = runSample sa $ mkStdGen 0
+removeDoor b sa = let (da, g) = runState (runSample sa) (mkStdGen 0)
                       in case da of
                         Uniform l -> uniform $ removeFst b l
                         _ -> error "not monty hall"
diff --git a/test/Normal10.hs b/test/Normal10.hs
--- a/test/Normal10.hs
+++ b/test/Normal10.hs
@@ -1,6 +1,6 @@
-import Data.Sample
-import Data.Sample.Types
-import Data.Sample.Lib
+import Data.Stochastic
+import Data.Stochastic.Types
+import Data.Stochastic.Internal
 
 import System.Random
 
diff --git a/test/Normal3.hs b/test/Normal3.hs
--- a/test/Normal3.hs
+++ b/test/Normal3.hs
@@ -1,6 +1,6 @@
-import Data.Sample
-import Data.Sample.Types
-import Data.Sample.Lib
+import Data.Stochastic
+import Data.Stochastic.Types
+import Data.Stochastic.Internal
 
 import System.Random
 
diff --git a/test/Swindler.hs b/test/Swindler.hs
--- a/test/Swindler.hs
+++ b/test/Swindler.hs
@@ -1,6 +1,6 @@
-import Data.Sample
-import Data.Sample.Lib
-import Data.Sample.Types
+import Data.Stochastic
+import Data.Stochastic.Internal
+import Data.Stochastic.Types
 
 import qualified Data.Sequence as S
 
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,8 +1,8 @@
 module Main where
 
-import Data.Sample
-import Data.Sample.Lib
-import Data.Sample.Types
+import Data.Stochastic
+import Data.Stochastic.Internal
+import Data.Stochastic.Types
 
 import qualified Data.Sequence as S
 
