diff --git a/Control/Monad/Ref.hs b/Control/Monad/Ref.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Ref.hs
@@ -0,0 +1,193 @@
+-- Copyright (c) 2006-2010
+--         The President and Fellows of Harvard College.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+--    notice, this list of conditions and the following disclaimer.
+-- 2. 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.
+-- 3. Neither the name of the University nor the names of its contributors
+--    may be used to endorse or promote products derived from this software
+--    without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY 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 UNIVERSITY 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.
+
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Ref
+-- Copyright   :  (c) Harvard University 2006-2010
+-- License     :  BSD-style
+-- Maintainer  :  mainland@eecs.harvard.edu
+--
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+--------------------------------------------------------------------------------
+
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Control.Monad.Ref (
+    MonadRef(..),
+    MonadAtomicRef(..)
+  ) where
+
+import Control.Concurrent.STM (STM)
+import Control.Concurrent.STM.TVar (TVar,
+                                    newTVar,
+                                    readTVar,
+                                    writeTVar)
+import Control.Monad.ST (ST)
+import Control.Monad.Cont (ContT)
+import Control.Monad.Error (ErrorT, Error)
+import Control.Monad.List (ListT)
+import Control.Monad.Reader (ReaderT)
+import Control.Monad.State.Lazy as Lazy (StateT)
+import Control.Monad.State.Strict as Strict (StateT)
+import Control.Monad.Trans (lift)
+import Control.Monad.Writer.Lazy as Lazy (WriterT)
+import Control.Monad.Writer.Strict as Strict (WriterT)
+import Data.IORef (IORef,
+                   atomicModifyIORef,
+                   modifyIORef,
+                   newIORef,
+                   readIORef,
+                   writeIORef)
+import Data.Monoid (Monoid)
+import Data.STRef (STRef,
+                   modifySTRef,
+                   newSTRef,
+                   readSTRef,
+                   writeSTRef)
+
+-- |The 'MonadRef' type class abstracts over the details of manipulating
+-- references, allowing one to write code that uses references and can operate
+-- in any monad that supports reference operations.
+
+class (Monad m) => MonadRef r m | m -> r where
+    -- |Create a new reference
+    newRef    :: a -> m (r a)
+    -- |Read the value of a reference
+    readRef   :: r a -> m a
+    -- |Write a new value to a reference
+    writeRef  :: r a -> a -> m ()
+    -- |Mutate the contents of a reference
+    modifyRef :: r a -> (a -> a) -> m ()
+    modifyRef r f = readRef r >>= writeRef r . f
+
+class (MonadRef r m) => MonadAtomicRef r m | m -> r where
+    -- |Atomically mutate the contents of a reference
+    atomicModifyRef :: r a -> (a -> (a, b)) -> m b
+
+instance MonadRef (STRef s) (ST s) where
+    newRef    = newSTRef
+    readRef   = readSTRef
+    writeRef  = writeSTRef
+    modifyRef = modifySTRef
+
+instance MonadRef IORef IO where
+    newRef    = newIORef
+    readRef   = readIORef
+    writeRef  = writeIORef
+    modifyRef = modifyIORef
+
+instance MonadRef TVar STM where
+    newRef    = newTVar
+    readRef   = readTVar
+    writeRef  = writeTVar
+
+instance MonadRef r m => MonadRef r (ContT r' m) where
+    newRef    r   = lift $ newRef    r
+    readRef   r   = lift $ readRef   r
+    writeRef  r x = lift $ writeRef  r x
+    modifyRef r f = lift $ modifyRef r f
+
+instance (Error e, MonadRef r m) => MonadRef r (ErrorT e m) where
+    newRef    r   = lift $ newRef    r
+    readRef   r   = lift $ readRef   r
+    writeRef  r x = lift $ writeRef  r x
+    modifyRef r f = lift $ modifyRef r f
+
+instance MonadRef r m => MonadRef r (ListT m) where
+    newRef    r   = lift $ newRef    r
+    readRef   r   = lift $ readRef   r
+    writeRef  r x = lift $ writeRef  r x
+    modifyRef r f = lift $ modifyRef r f
+
+instance MonadRef r m => MonadRef r (ReaderT r' m) where
+    newRef    r   = lift $ newRef    r
+    readRef   r   = lift $ readRef   r
+    writeRef  r x = lift $ writeRef  r x
+    modifyRef r f = lift $ modifyRef r f
+
+instance MonadRef r m => MonadRef r (Lazy.StateT s m) where
+    newRef    r   = lift $ newRef    r
+    readRef   r   = lift $ readRef   r
+    writeRef  r x = lift $ writeRef  r x
+    modifyRef r f = lift $ modifyRef r f
+
+instance MonadRef r m => MonadRef r (Strict.StateT s m) where
+    newRef    r   = lift $ newRef    r
+    readRef   r   = lift $ readRef   r
+    writeRef  r x = lift $ writeRef  r x
+    modifyRef r f = lift $ modifyRef r f
+
+instance (Monoid w, MonadRef r m) => MonadRef r (Lazy.WriterT w m) where
+    newRef    r   = lift $ newRef    r
+    readRef   r   = lift $ readRef   r
+    writeRef  r x = lift $ writeRef  r x
+    modifyRef r f = lift $ modifyRef r f
+
+instance (Monoid w, MonadRef r m) => MonadRef r (Strict.WriterT w m) where
+    newRef    r   = lift $ newRef    r
+    readRef   r   = lift $ readRef   r
+    writeRef  r x = lift $ writeRef  r x
+    modifyRef r f = lift $ modifyRef r f
+
+instance MonadAtomicRef IORef IO where
+    atomicModifyRef = atomicModifyIORef
+
+instance MonadAtomicRef TVar STM where
+    atomicModifyRef r f = do x <- readRef r
+                             let (x', y) = f x
+                             writeRef r x'
+                             return y
+
+instance MonadAtomicRef r m => MonadAtomicRef r (ContT r' m) where
+    atomicModifyRef r f = lift $ atomicModifyRef r f
+
+instance (Error e, MonadAtomicRef r m) => MonadAtomicRef r (ErrorT e m) where
+    atomicModifyRef r f = lift $ atomicModifyRef r f
+
+instance MonadAtomicRef r m => MonadAtomicRef r (ListT m) where
+    atomicModifyRef r f = lift $ atomicModifyRef r f
+
+instance MonadAtomicRef r m => MonadAtomicRef r (ReaderT r' m) where
+    atomicModifyRef r f = lift $ atomicModifyRef r f
+
+instance MonadAtomicRef r m => MonadAtomicRef r (Lazy.StateT s m) where
+    atomicModifyRef r f = lift $ atomicModifyRef r f
+
+instance MonadAtomicRef r m => MonadAtomicRef r (Strict.StateT s m) where
+    atomicModifyRef r f = lift $ atomicModifyRef r f
+
+instance (Monoid w, MonadAtomicRef r m) => MonadAtomicRef r (Lazy.WriterT w m) where
+    atomicModifyRef r f = lift $ atomicModifyRef r f
+
+instance (Monoid w, MonadAtomicRef r m) => MonadAtomicRef r (Strict.WriterT w m) where
+    atomicModifyRef r f = lift $ atomicModifyRef r f
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2006-2010
+        The President and Fellows of Harvard College.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. 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.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY 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 UNIVERSITY 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 @@
+import Distribution.Simple
+
+main = defaultMain
diff --git a/ref-mtl.cabal b/ref-mtl.cabal
new file mode 100644
--- /dev/null
+++ b/ref-mtl.cabal
@@ -0,0 +1,30 @@
+name:           ref-mtl
+version:        0.2
+cabal-version:  >= 1.6
+license:        BSD3
+license-file:   LICENSE
+copyright:      (c) 2006-2010 Harvard University
+author:         Geoffrey Mainland <mainland@eecs.harvard.edu>
+maintainer:     mainland@eecs.harvard.edu
+stability:      alpha
+homepage:       http://www.eecs.harvard.edu/~mainland/
+category:       Control
+synopsis:       A type class for monads with references using type families.
+description:    Contains a 'MonadRef' type class that abstracts over the
+		details of manipulating references, allowing one to write code
+		that can operate in either the ST monad or the IO monad.
+
+build-type:     Simple
+
+library
+  exposed-modules:
+    Control.Monad.Ref
+
+  build-depends:
+    base >= 4 && < 5,
+    stm >= 2.1 && < 2.2,
+    mtl >= 1.1 && < 1.2
+
+source-repository head
+  type:     svn
+  location: http://senseless.eecs.harvard.edu/repos/mainland-projects/ref-mtl/trunk/
