diff --git a/Control/Comonad/Representable/Store.hs b/Control/Comonad/Representable/Store.hs
deleted file mode 100644
--- a/Control/Comonad/Representable/Store.hs
+++ /dev/null
@@ -1,116 +0,0 @@
-{-# LANGUAGE TypeFamilies
-           , FlexibleContexts
-           , FlexibleInstances
-           , MultiParamTypeClasses
-           , UndecidableInstances #-}
-----------------------------------------------------------------------
--- |
--- Module      :  Control.Comonad.Representable.Store
--- Copyright   :  (c) Edward Kmett & Sjoerd Visscher 2011
--- License     :  BSD3
--- 
--- Maintainer  :  ekmett@gmail.com
--- Stability   :  experimental
--- 
--- A generalized Store comonad, parameterized by a Representable functor.
--- The representation of that functor serves as the index of the store.
-----------------------------------------------------------------------
-module Control.Comonad.Representable.Store
-   ( Store
-   , store
-   , runStore
-   , StoreT(..)
-   , storeT
-   , runStoreT
-   , pos
-   , peek
-   , peeks
-   , seek
-   , seeks
-   ) where
-
-import Control.Comonad
-import Control.Applicative
-import Data.Key
-import Data.Functor.Apply
-import Data.Semigroup
-import Control.Comonad.Hoist.Class
-import Control.Comonad.Env.Class
-import Control.Comonad.Traced.Class
-import Control.Comonad.Cofree.Class
-import Control.Comonad.Trans.Class
-import Control.Comonad.Store.Class
-import Control.Monad.Identity
-import Data.Functor.Representable
-
--- | A memoized store comonad parameterized by a representable functor @g@, where 
--- the representatation of @g@, @Key g@ is the index of the store.
---
-type Store g = StoreT g Identity
-
--- | Construct a store comonad computation from a function and a current index.
--- (The inverse of 'runStore'.)
-store :: Representable g
-      => (Key g -> a)  -- ^ computation
-      -> Key g         -- ^ index
-      -> Store g a
-store = storeT . Identity
-
--- | Unwrap a state monad computation as a function.
--- (The inverse of 'state'.)
-runStore :: Indexable g
-         => Store g a           -- ^ a store to access
-         -> (Key g -> a, Key g) -- ^ initial state
-runStore (StoreT (Identity ga) k) = (index ga, k)
-
--- ---------------------------------------------------------------------------
--- | A store transformer comonad parameterized by:
---
---   * @g@ - A representable functor used to memoize results for an index @Key g@
---
---   * @w@ - The inner comonad.
-data StoreT g w a = StoreT (w (g a)) (Key g)
-
-storeT :: (Functor w, Representable g) => w (Key g -> a) -> Key g -> StoreT g w a 
-storeT = StoreT . fmap tabulate
-
-runStoreT :: (Functor w, Indexable g) => StoreT g w a -> (w (Key g -> a), Key g)
-runStoreT (StoreT w s) = (index <$> w, s)
-
-instance (Comonad w, Representable g, Key g ~ s) => ComonadStore s (StoreT g w) where
-  pos (StoreT _ s) = s
-  peek s (StoreT w _) = extract w `index` s
-  peeks f (StoreT w s) = extract w `index` f s
-  seek s (StoreT w _) = StoreT w s
-  seeks f (StoreT w s) = StoreT w (f s)
-
-instance (Functor w, Functor g) => Functor (StoreT g w) where
-  fmap f (StoreT w s) = StoreT (fmap (fmap f) w) s
-
-instance (Apply w, Semigroup (Key g), Representable g) => Apply (StoreT g w) where
-  StoreT ff m <.> StoreT fa n = StoreT (apRep <$> ff <.> fa) (m <> n)
-
-instance (Applicative w, Semigroup (Key g), Monoid (Key g), Representable g) => Applicative (StoreT g w) where
-  pure a = StoreT (pure (pureRep a)) mempty
-  StoreT ff m <*> StoreT fa n = StoreT (apRep <$> ff <*> fa) (m `mappend` n)
-
-instance (Extend w, Representable g) => Extend (StoreT g w) where
-  duplicate (StoreT wf s) = StoreT (extend (tabulate . StoreT) wf) s
-
-instance (Comonad w, Representable g) => Comonad (StoreT g w) where
-  extract (StoreT wf s) = index (extract wf) s
-
-instance Indexable g => ComonadTrans (StoreT g) where
-  lower (StoreT w s) = fmap (`index` s) w
-
-instance ComonadHoist (StoreT g) where
-  cohoist (StoreT w s) = StoreT (Identity (extract w)) s
-
-instance (ComonadTraced m w, Representable g) => ComonadTraced m (StoreT g w) where
-  trace m = trace m . lower
-
-instance (ComonadEnv m w, Representable g) => ComonadEnv m (StoreT g w) where 
-  ask = ask . lower
-
-instance (Representable g, ComonadCofree f w) => ComonadCofree f (StoreT g w) where
-  unwrap (StoreT w s) = fmap (`StoreT` s) (unwrap w)
diff --git a/Control/Monad/Representable/Reader.hs b/Control/Monad/Representable/Reader.hs
deleted file mode 100644
--- a/Control/Monad/Representable/Reader.hs
+++ /dev/null
@@ -1,157 +0,0 @@
-{-# LANGUAGE GADTs, TypeFamilies, TypeOperators, CPP, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, TypeSynonymInstances #-}
-{-# OPTIONS_GHC -fenable-rewrite-rules -fno-warn-orphans #-}
-----------------------------------------------------------------------
--- |
--- Module      :  Control.Monad.Representable.Reader
--- Copyright   :  (c) Edward Kmett 2011,
---                (c) Conal Elliott 2008
--- License     :  BSD3
---
--- Maintainer  :  ekmett@gmail.com
--- Stability   :  experimental
---
--- Representable functors on Hask all monads, being isomorphic to
--- a reader monad.
-----------------------------------------------------------------------
-
-module Control.Monad.Representable.Reader
-  (
-  -- * Representable functor monad
-    Reader, runReader
-  -- * Monad Transformer
-  , ReaderT(..), readerT, runReaderT
-  , ask
-  , local
-  , module Data.Functor.Representable
-  ) where
-
-import Control.Applicative
-import Control.Comonad
-import Control.Monad.Reader.Class
-import Control.Monad.Writer.Class as Writer
-import Control.Monad.Trans.Class
-import Control.Monad.IO.Class
-import Data.Distributive
-import Data.Key
-import Data.Functor.Bind
-import Data.Functor.Identity
-import Data.Functor.Representable
-import Data.Foldable
-import Data.Traversable
-import Data.Semigroup
-import Data.Semigroup.Foldable
-import Data.Semigroup.Traversable
-import Prelude hiding (lookup,zipWith)
-
-type Reader f = ReaderT f Identity
-
-runReader :: Indexable f => Reader f b -> Key f -> b
-runReader = fmap runIdentity . runReaderT
-
--- * This 'representable monad transformer' transforms any monad @m@ with a 'Representable' 'Monad'.
---   This monad in turn is also representable if @m@ is 'Representable'.
-newtype ReaderT f m b = ReaderT { getReaderT :: f (m b) }
-
-readerT :: Representable f => (Key f -> m b) -> ReaderT f m b
-readerT = ReaderT . tabulate
-
-runReaderT :: Indexable f => ReaderT f m b -> Key f -> m b
-runReaderT = index . getReaderT
-
-type instance Key (ReaderT f m) = (Key f, Key m)
-
-instance (Functor f, Functor m) => Functor (ReaderT f m) where
-  fmap f = ReaderT . fmap (fmap f) . getReaderT
-
-instance (Indexable f, Indexable m) => Indexable (ReaderT f m) where
-  index = uncurry . fmap index . index . getReaderT
-
-instance (Representable f, Representable m) => Representable (ReaderT f m) where
-  tabulate = ReaderT . tabulate . fmap tabulate . curry
-
-instance (Representable f, Apply m) => Apply (ReaderT f m) where
-  ReaderT ff <.> ReaderT fa = ReaderT (unrep ((<.>) <$> Rep ff <.> Rep fa))
-
-instance (Representable f, Applicative m) => Applicative (ReaderT f m) where
-  pure = ReaderT . pureRep . pure
-  ReaderT ff <*> ReaderT fa = ReaderT (unrep ((<*>) <$> Rep ff <*> Rep fa))
-
-instance (Representable f, Bind m) => Bind (ReaderT f m) where
-  ReaderT fm >>- f = ReaderT $ tabulate (\a -> index fm a >>- flip index a . getReaderT . f)
-
-instance (Representable f, Monad m) => Monad (ReaderT f m) where
-  return = ReaderT . pureRep . return
-  ReaderT fm >>= f = ReaderT $ tabulate (\a -> index fm a >>= flip index a . getReaderT . f)
-
-#if __GLASGOW_HASKELL >= 704
-
-instance (Representable f, Monad m, Key f ~ e) => MonadReader e (ReaderT f m) where
-  ask = ReaderT (tabulate return)
-  local f m = readerT $ \r -> runReaderT m (f r)
-#if MIN_VERSION_transformers(0,3,0)
-  reader = readerT . fmap return
-#endif
-
-#endif
-
-instance Representable f => MonadTrans (ReaderT f) where
-  lift = ReaderT . pureRep
-
-instance (Representable f, Distributive m) => Distributive (ReaderT f m) where
-  distribute = ReaderT . fmapRep distribute . unrep . collect (Rep . getReaderT)
-
-instance (Representable f, Keyed m) => Keyed (ReaderT f m) where
-  mapWithKey f = ReaderT . mapWithKeyRep (\k -> mapWithKey (f . (,) k)) . getReaderT
-
-instance (Indexable f, Lookup m) => Lookup (ReaderT f m) where
-  lookup (k,k') (ReaderT fm) = lookup k' (index fm k)
-
-instance (Representable f, Representable m, Semigroup (Key f), Semigroup (Key m)) => Extend (ReaderT f m) where
-  extend = extendRep
-  duplicate = duplicateRep
-
-instance (Representable f, Zip m) => Zip (ReaderT f m) where
-  zipWith f (ReaderT as) (ReaderT bs) = ReaderT $ tabulate $ \i -> zipWith f (index as i) (index bs i)
-
-instance (Representable f, ZipWithKey m) => ZipWithKey (ReaderT f m) where
-  zipWithKey f (ReaderT as) (ReaderT bs) = ReaderT $ tabulate $ \i -> zipWithKey (f . (,) i) (index as i) (index bs i)
-
-instance (Representable f, Representable m, Semigroup (Key f), Semigroup (Key m), Monoid (Key f), Monoid (Key m)) => Comonad (ReaderT f m) where
-  extract = extractRep
-
-instance (Representable f, MonadIO m) => MonadIO (ReaderT f m) where
-  liftIO = lift . liftIO
-
-instance (Representable f, MonadWriter w m) => MonadWriter w (ReaderT f m) where
-  tell = lift . tell
-  listen (ReaderT m) = ReaderT $ tabulate $ Writer.listen . index m
-  pass (ReaderT m) = ReaderT $ tabulate $ Writer.pass . index m
-
--- misc. instances that can exist, but aren't particularly about representability
-
-instance (Adjustable f, Adjustable m) => Adjustable (ReaderT f m) where
-  adjust f (kf,km) = ReaderT . adjust (adjust f km) kf . getReaderT
-
-instance (Foldable f, Foldable m) => Foldable (ReaderT f m) where
-  foldMap f = foldMap (foldMap f) . getReaderT
-
-instance (Foldable1 f, Foldable1 m) => Foldable1 (ReaderT f m) where
-  foldMap1 f = foldMap1 (foldMap1 f) . getReaderT
-
-instance (FoldableWithKey f, FoldableWithKey m) => FoldableWithKey (ReaderT f m) where
-  foldMapWithKey f = foldMapWithKey (\k -> foldMapWithKey (f . (,) k)) . getReaderT
-
-instance (FoldableWithKey1 f, FoldableWithKey1 m) => FoldableWithKey1 (ReaderT f m) where
-  foldMapWithKey1 f = foldMapWithKey1 (\k -> foldMapWithKey1 (f . (,) k)) . getReaderT
-
-instance (Traversable f, Traversable m) => Traversable (ReaderT f m) where
-  traverse f = fmap ReaderT . traverse (traverse f) . getReaderT
-
-instance (Traversable1 f, Traversable1 m) => Traversable1 (ReaderT f m) where
-  traverse1 f = fmap ReaderT . traverse1 (traverse1 f) . getReaderT
-
-instance (Representable f, TraversableWithKey f, TraversableWithKey m) => TraversableWithKey (ReaderT f m) where
-  traverseWithKey f = fmap ReaderT . traverseWithKey (\k -> traverseWithKey (f . (,) k)) . getReaderT
-
-instance (Representable f, TraversableWithKey1 f, TraversableWithKey1 m) => TraversableWithKey1 (ReaderT f m) where
-  traverseWithKey1 f = fmap ReaderT . traverseWithKey1 (\k -> traverseWithKey1 (f . (,) k)) . getReaderT
diff --git a/Control/Monad/Representable/State.hs b/Control/Monad/Representable/State.hs
deleted file mode 100644
--- a/Control/Monad/Representable/State.hs
+++ /dev/null
@@ -1,218 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE UndecidableInstances #-}
-----------------------------------------------------------------------
--- |
--- Module      :  Control.Monad.Representable.State
--- Copyright   :  (c) Edward Kmett & Sjoerd Visscher 2011
--- License     :  BSD3
---
--- Maintainer  :  ekmett@gmail.com
--- Stability   :  experimental
---
--- A generalized State monad, parameterized by a Representable functor.
--- The representation of that functor serves as the state.
-----------------------------------------------------------------------
-module Control.Monad.Representable.State
-   ( State
-   , runState
-   , evalState
-   , execState
-   , mapState
-   , StateT(..)
-   , stateT
-   , runStateT
-   , evalStateT
-   , execStateT
-   , mapStateT
-   , liftCallCC
-   , liftCallCC'
-   , get
-   , gets
-   , put
-   , modify
-   ) where
-
-import Control.Applicative
-import Data.Key
-import Data.Functor.Bind
-import Data.Functor.Bind.Trans
-import Control.Monad.State.Class
-import Control.Monad.Cont.Class
-import Control.Monad.Reader.Class
-import Control.Monad.Writer.Class
-import Control.Monad.Free.Class
-import Control.Monad.Trans.Class
-import Control.Monad.Identity
-import Data.Functor.Representable
-
--- ---------------------------------------------------------------------------
--- | A memoized state monad parameterized by a representable functor @g@, where
--- the representatation of @g@, @Key g@ is the state to carry.
---
--- The 'return' function leaves the state unchanged, while @>>=@ uses
--- the final state of the first computation as the initial state of
--- the second.
-type State g = StateT g Identity
-
-
--- | Unwrap a state monad computation as a function.
--- (The inverse of 'state'.)
-runState :: Indexable g
-         => State g a   -- ^ state-passing computation to execute
-         -> Key g       -- ^ initial state
-         -> (a, Key g)  -- ^ return value and final state
-runState m = runIdentity . runStateT m
-
--- | Evaluate a state computation with the given initial state
--- and return the final value, discarding the final state.
---
--- * @'evalState' m s = 'fst' ('runState' m s)@
-evalState :: Indexable g
-          => State g a  -- ^state-passing computation to execute
-          -> Key g      -- ^initial value
-          -> a          -- ^return value of the state computation
-evalState m s = fst (runState m s)
-
--- | Evaluate a state computation with the given initial state
--- and return the final state, discarding the final value.
---
--- * @'execState' m s = 'snd' ('runState' m s)@
-execState :: Indexable g
-          => State g a  -- ^state-passing computation to execute
-          -> Key g      -- ^initial value
-          -> Key g      -- ^final state
-execState m s = snd (runState m s)
-
--- | Map both the return value and final state of a computation using
--- the given function.
---
--- * @'runState' ('mapState' f m) = f . 'runState' m@
-mapState :: Functor g => ((a, Key g) -> (b, Key g)) -> State g a -> State g b
-mapState f = mapStateT (Identity . f . runIdentity)
-
--- ---------------------------------------------------------------------------
--- | A state transformer monad parameterized by:
---
---   * @g@ - A representable functor used to memoize results for a state @Key g@
---
---   * @m@ - The inner monad.
---
--- The 'return' function leaves the state unchanged, while @>>=@ uses
--- the final state of the first computation as the initial state of
--- the second.
-newtype StateT g m a = StateT { getStateT :: g (m (a, Key g)) }
-
-stateT :: Representable g => (Key g -> m (a, Key g)) -> StateT g m a
-stateT = StateT . tabulate
-
-runStateT :: Indexable g => StateT g m a -> Key g -> m (a, Key g)
-runStateT (StateT m) = index m
-
-mapStateT :: Functor g => (m (a, Key g) -> n (b, Key g)) -> StateT g m a -> StateT g n b
-mapStateT f (StateT m) = StateT (fmap f m)
-
--- | Evaluate a state computation with the given initial state
--- and return the final value, discarding the final state.
---
--- * @'evalStateT' m s = 'liftM' 'fst' ('runStateT' m s)@
-evalStateT :: (Indexable g, Monad m) => StateT g m a -> Key g -> m a
-evalStateT m s = do
-    (a, _) <- runStateT m s
-    return a
-
--- | Evaluate a state computation with the given initial state
--- and return the final state, discarding the final value.
---
--- * @'execStateT' m s = 'liftM' 'snd' ('runStateT' m s)@
-execStateT :: (Indexable g, Monad m) => StateT g m a -> Key g -> m (Key g)
-execStateT m s = do
-    (_, s') <- runStateT m s
-    return s'
-
-instance (Functor g, Functor m) => Functor (StateT g m) where
-  fmap f = StateT . fmap (fmap (\ ~(a, s) -> (f a, s))) . getStateT
-
-instance (Functor g, Indexable g, Bind m) => Apply (StateT g m) where
-  mf <.> ma = mf >>- \f -> fmap f ma
-
-instance (Representable g, Functor m, Monad m) => Applicative (StateT g m) where
-  pure = StateT . leftAdjunctRep return
-  mf <*> ma = mf >>= \f -> fmap f ma
-
-instance (Functor g, Indexable g, Bind m) => Bind (StateT g m) where
-  StateT m >>- f = StateT $ fmap (>>- rightAdjunctRep (runStateT . f)) m
-
-instance (Representable g, Monad m) => Monad (StateT g m) where
-  return = StateT . leftAdjunctRep return
-  StateT m >>= f = StateT $ fmap (>>= rightAdjunctRep (runStateT . f)) m
-
-instance Representable f => BindTrans (StateT f) where
-  liftB m = stateT $ \s -> fmap (\a -> (a, s)) m
-
-instance Representable f => MonadTrans (StateT f) where
-  lift m = stateT $ \s -> liftM (\a -> (a, s)) m
-
-instance (Representable g, Monad m, Key g ~ s) => MonadState s (StateT g m) where
-  get = stateT $ \s -> return (s, s)
-  put s = StateT $ pureRep $ return ((),s)
-#if MIN_VERSION_transformers(0,3,0)
-  state f = stateT (return . f)
-#endif
-
--- get :: (Representable g, Monad m) => StateT g m (Key g)
--- put :: (Applicative g, Monad m) => Key g -> StateT g m ()
-
--- gets :: (Representable g, Monad m) => (Key g -> s) -> StateT g m s
--- gets f = liftM f get
-
--- modify :: (Representable g, Monad m) => (Key g -> Key g) -> StateT g m ()
--- modify f = stateT $ \s -> return ((), f s)
-
-instance (Representable g, MonadReader e m) => MonadReader e (StateT g m) where
-  ask = lift ask
-  local = mapStateT . local
-
-instance (Representable g, MonadWriter w m) => MonadWriter w (StateT g m) where
-  tell = lift . tell
-  listen = mapStateT $ \ma -> do
-     ((a,s'), w) <- listen ma
-     return ((a,w), s')
-  pass = mapStateT $ \ma -> pass $ do
-    ((a, f), s') <- ma
-    return ((a, s'), f)
-
-instance (Representable g, MonadCont m) => MonadCont (StateT g m) where
-    callCC = liftCallCC' callCC
-
-instance (Functor f, Representable g, MonadFree f m) => MonadFree f (StateT g m) where
-    wrap as = stateT $ \s -> wrap (fmap (`runStateT` s) as)
-
-leftAdjunctRep :: Representable u => ((a, Key u) -> b) -> a -> u b
-leftAdjunctRep f a = tabulate (\s -> f (a,s))
-
-rightAdjunctRep :: Indexable u => (a -> u b) -> (a, Key u) -> b
-rightAdjunctRep f ~(a, k) = f a `index` k
-
--- | Uniform lifting of a @callCC@ operation to the new monad.
--- This version rolls back to the original state on entering the
--- continuation.
-liftCallCC :: Representable g => ((((a,Key g) -> m (b,Key g)) -> m (a,Key g)) -> m (a,Key g)) ->
-    ((a -> StateT g m b) -> StateT g m a) -> StateT g m a
-liftCallCC callCC' f = stateT $ \s ->
-    callCC' $ \c ->
-    runStateT (f (\a -> StateT $ pureRep $ c (a, s))) s
-
--- | In-situ lifting of a @callCC@ operation to the new monad.
--- This version uses the current state on entering the continuation.
--- It does not satisfy the laws of a monad transformer.
-liftCallCC' :: Representable g => ((((a,Key g) -> m (b,Key g)) -> m (a,Key g)) -> m (a,Key g)) ->
-    ((a -> StateT g m b) -> StateT g m a) -> StateT g m a
-liftCallCC' callCC' f = stateT $ \s ->
-    callCC' $ \c ->
-    runStateT (f (\a -> stateT $ \s' -> c (a, s'))) s
-
diff --git a/Data/Functor/Corepresentable.hs b/Data/Functor/Corepresentable.hs
deleted file mode 100644
--- a/Data/Functor/Corepresentable.hs
+++ /dev/null
@@ -1,122 +0,0 @@
-{-# LANGUAGE TypeFamilies, FlexibleContexts, FlexibleInstances #-}
-{-# OPTIONS_GHC -fenable-rewrite-rules #-}
-
-----------------------------------------------------------------------
--- |
--- Module      :  Data.Functor.Corepresentable
--- Copyright   :  (c) Edward Kmett 2011
--- License     :  BSD3
--- 
--- Maintainer  :  ekmett@gmail.com
--- Stability   :  experimental
--- 
--- Representable contravariant endofunctors over the category of Haskell 
--- types are isomorphic to @(_ -> r)@ and resemble mappings to a
--- fixed range.
-----------------------------------------------------------------------
-
-module Data.Functor.Corepresentable
-  ( 
-  -- * Values
-    Value
-  -- * Contravariant Keyed
-  , Valued(..)
-  -- * Contravariant Indexed
-  , Coindexed(..)
-  -- * Representable Contravariant Functors
-  , Corepresentable(..)
-  -- * Default definitions
-  , contramapDefault
-  , contramapWithValueDefault
-  ) where
-
-import Control.Monad.Reader
-import Data.Functor.Contravariant
-import Data.Functor.Product
-import Data.Functor.Coproduct
-import Prelude hiding (lookup)
-
-type family Value (f :: * -> *)
-
--- | Dual to 'Keyed'.
-class Contravariant f => Valued f where
-  contramapWithValue :: (b -> Either a (Value f)) -> f a -> f b
-
--- | Dual to 'Indexed'.
-class Coindexed f where
-  coindex :: f a -> a -> Value f
-
--- | A 'Functor' @f@ is 'Corepresentable' if 'corep' and 'coindex' witness an isomorphism to @(_ -> Value f)@.
---
--- > tabulate . index = id
--- > index . tabulate = id
--- > tabulate . return f = return f
-
-class (Coindexed f, Valued f) => Corepresentable f where
-  -- | > contramap f (corep g) = corep (g . f)
-  corep :: (a -> Value f) -> f a
-
-{-# RULES
-"corep/coindex" forall t. corep (coindex t) = t
- #-}
-
--- * Default definitions
-
-contramapDefault :: Corepresentable f => (a -> b) -> f b -> f a
-contramapDefault f = corep . (. f) . coindex 
-
-contramapWithValueDefault :: Corepresentable f => (b -> Either a (Value f)) -> f a -> f b
-contramapWithValueDefault f p = corep $ either (coindex p) id . f
-
--- * Dual arrows
-
-type instance Value (Op r) = r
-
-instance Valued (Op r) where
-  contramapWithValue = contramapWithValueDefault
-
-instance Coindexed (Op r) where
-  coindex = getOp
-
-instance Corepresentable (Op r) where
-  corep = Op
-
--- * Predicates
-
-type instance Value Predicate = Bool
-
-instance Valued Predicate where
-  contramapWithValue = contramapWithValueDefault
-
-instance Coindexed Predicate where
-  coindex = getPredicate
-
-instance Corepresentable Predicate where
-  corep = Predicate
-
--- * Products
-
-type instance Value (Product f g) = (Value f, Value g)
-
-instance (Valued f, Valued g) => Valued (Product f g) where
-  -- contramapWithValue :: (b -> Either a (Value f)) -> f a -> f b
-  contramapWithValue h (Pair f g) = Pair 
-      (contramapWithValue (fmap fst . h) f)
-      (contramapWithValue (fmap snd . h) g)
-      -- (contramapWithValue (either id snd . h) g)
-      -- (either g snd . h)
-
-instance (Coindexed f, Coindexed g) => Coindexed (Product f g) where
-  coindex (Pair f g) a = (coindex f a, coindex g a)
-
-instance (Corepresentable f, Corepresentable g) => Corepresentable (Product f g) where
-  corep f = Pair (corep (fst . f)) (corep (snd . f))
-
-
--- * Coproducts
-
-type instance Value (Coproduct f g) = Either (Value f) (Value g)
-
-instance (Coindexed f, Coindexed g) => Coindexed (Coproduct f g) where
-  coindex (Coproduct (Left f)) a  = Left  $ coindex f a 
-  coindex (Coproduct (Right g)) a = Right $ coindex g a
diff --git a/Data/Functor/Representable.hs b/Data/Functor/Representable.hs
deleted file mode 100644
--- a/Data/Functor/Representable.hs
+++ /dev/null
@@ -1,227 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# OPTIONS_GHC -fenable-rewrite-rules #-}
-----------------------------------------------------------------------
--- |
--- Module      :  Data.Functor.Representable
--- Copyright   :  (c) Edward Kmett 2011
--- License     :  BSD3
--- 
--- Maintainer  :  ekmett@gmail.com
--- Stability   :  experimental
--- 
--- Representable endofunctors over the category of Haskell types are 
--- isomorphic to the reader monad and so inherit a very large number
--- of properties for free.
-----------------------------------------------------------------------
-
-module Data.Functor.Representable
-  (
-  -- * Representable Functors
-    Representable(..)
-  -- * Wrapped representable functors
-  , Rep(..)
-  -- ** Representable Lenses
-  , repLens
-  -- * Default definitions
-  -- ** Functor
-  , fmapRep
-  -- ** Distributive
-  , distributeRep
-  -- ** Keyed
-  , mapWithKeyRep
-  -- ** Apply/Applicative
-  , apRep
-  , pureRep
-  , liftR2
-  , liftR3
-  -- ** Bind/Monad
-  , bindRep
-  , bindWithKeyRep
-  -- ** Zip/ZipWithKey
-  , zipWithRep
-  , zipWithKeyRep
-  -- ** MonadReader
-  , askRep
-  , localRep
-  -- ** Extend
-  , duplicateRep
-  , extendRep
-  -- ** Comonad
-  , extractRep
-  ) where
-
-import Control.Applicative
-import Control.Comonad
-import Control.Comonad.Trans.Class
-import Control.Comonad.Trans.Traced
-import Control.Comonad.Cofree
-import Control.Monad.Trans.Identity
-import Control.Monad.Reader
-import Data.Distributive
-import Data.Key
-import Data.Functor.Bind
-import Data.Functor.Identity
-import Data.Functor.Compose
-import Data.Functor.Product
-import Data.Lens.Common
-import qualified Data.Sequence as Seq
-import Data.Semigroup hiding (Product)
-import Prelude hiding (lookup)
-
--- | A 'Functor' @f@ is 'Representable' if 'tabulate' and 'index' witness an isomorphism to @(->) x@.
---
--- > tabulate . index = id
--- > index . tabulate = id
--- > tabulate . return f = return f
-
-class (Functor f, Indexable f) => Representable f where
-  -- | > fmap f . tabulate = tabulate . fmap f
-  tabulate :: (Key f -> a) -> f a
-
-{-# RULES
-"tabulate/index" forall t. tabulate (index t) = t
- #-}
-
--- * Default definitions
-
-fmapRep :: Representable f => (a -> b) -> f a -> f b
-fmapRep f = tabulate . fmap f . index
-
-mapWithKeyRep :: Representable f => (Key f -> a -> b) -> f a -> f b
-mapWithKeyRep f = tabulate . (<*>) f . index
-
-pureRep :: Representable f => a -> f a
-pureRep = tabulate . const
-
-bindRep :: Representable f => f a -> (a -> f b) -> f b
-bindRep m f = tabulate (\a -> index (f (index m a)) a)
-
-bindWithKeyRep :: Representable f => f a -> (Key f -> a -> f b) -> f b
-bindWithKeyRep m f = tabulate (\a -> index (f a (index m a)) a)
-
-askRep :: Representable f => f (Key f)
-askRep = tabulate id
-
-localRep :: Representable f => (Key f -> Key f) -> f a -> f a
-localRep f m = tabulate (index m . f)
-
-apRep :: Representable f => f (a -> b) -> f a -> f b
-apRep f g = tabulate (index f <*> index g)
-
-zipWithRep :: Representable f => (a -> b -> c) -> f a -> f b -> f c
-zipWithRep f g h = tabulate $ \k -> f (index g k) (index h k)
-
-zipWithKeyRep :: Representable f => (Key f -> a -> b -> c) -> f a -> f b -> f c
-zipWithKeyRep f g h = tabulate $ \k -> f k (index g k) (index h k)
-
-distributeRep :: (Representable f, Functor w) => w (f a) -> f (w a)
-distributeRep wf = tabulate (\k -> fmap (`index` k) wf)
-
-duplicateRep :: (Representable f, Semigroup (Key f)) => f a -> f (f a)
-duplicateRep w = tabulate (\m -> tabulate (index w . (<>) m))
-
-extendRep :: (Representable f, Semigroup (Key f)) => (f a -> b) -> f a -> f b
-extendRep f w = tabulate (\m -> f (tabulate (index w . (<>) m)))
-
-extractRep :: (Indexable f, Monoid (Key f)) => f a -> a
-extractRep fa = index fa mempty
-
--- | We extend lens across a representable functor, due to the preservation of limits.
-repLens :: Representable f => Lens a b -> Lens (f a) (f b)
-repLens l = lens (fmapRep (l ^$)) $ \a b -> unrep $ liftA2 (l ^=) (Rep a) (Rep b)
-
--- * Instances
-
-instance Representable Identity where
-  tabulate f = Identity (f ())
-
-instance Representable m => Representable (IdentityT m) where
-  tabulate = IdentityT . tabulate
-
-instance Representable ((->) e) where
-  tabulate = id
-
-instance Representable m => Representable (ReaderT e m) where
-  tabulate = ReaderT . fmap tabulate . curry 
-
-instance (Representable f, Representable g) => Representable (Compose f g) where
-  tabulate = Compose . tabulate . fmap tabulate . curry
-
-instance Representable w => Representable (TracedT s w) where
-  -- tabulate = TracedT . collect tabulate . curry
-  tabulate = TracedT . unrep . collect (Rep . tabulate) . curry
-
-instance (Representable f, Representable g) => Representable (Product f g) where
-  tabulate f = Pair (tabulate (f . Left)) (tabulate (f . Right))
-
-instance Representable f => Representable (Cofree f) where
-  tabulate f = f Seq.empty :< tabulate (\k -> tabulate (f . (k Seq.<|)))
-
-
-newtype Rep f a = Rep { unrep :: f a }
-
-type instance Key (Rep f) = Key f
-
-instance Representable f => Representable (Rep f) where
-  tabulate = Rep . tabulate
-
-instance Indexable f => Indexable (Rep f) where
-  index (Rep f) i = index f i
-
-instance Representable f => Keyed (Rep f) where
-  mapWithKey = mapWithKeyRep
-
-instance Indexable f => Lookup (Rep f) where
-  lookup = lookupDefault
-
-instance Representable f => Functor (Rep f) where
-  fmap = fmapRep
-
-instance Representable f => Apply (Rep f) where
-  (<.>) = apRep
-
-instance Representable f => Applicative (Rep f) where
-  pure = pureRep
-  (<*>) = apRep
-
-instance Representable f => Distributive (Rep f) where
-  distribute = distributeRep
-
-instance Representable f => Bind (Rep f) where
-  (>>-) = bindRep
-
-instance Representable f => Monad (Rep f) where
-  return = pureRep
-  (>>=) = bindRep
-
-#if __GLASGOW_HASKELL__ >= 704
-instance (Representable f, Key f ~ a) => MonadReader a (Rep f) where
-  ask = askRep
-  local = localRep
-#endif
-
-instance Representable f => Zip (Rep f) where
-  zipWith = zipWithRep
-
-instance Representable f => ZipWithKey (Rep f) where
-  zipWithKey = zipWithKeyRep
-
-instance (Representable f, Semigroup (Key f)) => Extend (Rep f) where
-  extend = extendRep
-
-instance (Representable f, Semigroup (Key f), Monoid (Key f)) => Comonad (Rep f) where
-  extract = extractRep
-
-instance ComonadTrans Rep where
-  lower (Rep f) = f
-
-liftR2 :: Representable f => (a -> b -> c) -> f a -> f b -> f c
-liftR2 f fa fb = tabulate $ \i -> f (index fa i) (index fb i)
-
-liftR3 :: Representable f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
-liftR3 f fa fb fc = tabulate $ \i -> f (index fa i) (index fb i) (index fc i)
diff --git a/representable-functors.cabal b/representable-functors.cabal
--- a/representable-functors.cabal
+++ b/representable-functors.cabal
@@ -1,6 +1,6 @@
 name:          representable-functors
 category:      Monads, Functors, Data Structures
-version:       2.5
+version:       3.0
 license:       BSD3
 cabal-version: >= 1.6
 license-file:  LICENSE
@@ -20,6 +20,8 @@
   location: git://github.com/ekmett/representable-functors.git
 
 library
+  hs-source-dirs: src
+
   other-extensions:
     CPP
     FlexibleContexts
@@ -34,19 +36,18 @@
   build-depends:
     array                >= 0.3.0.2 && < 0.5,
     base                 >= 4       && < 5,
-    comonad              >= 1.1.1.5 && < 1.2,
+    comonad              >= 3.0     && < 3.1,
+    comonad-transformers >= 3.0     && < 3.1,
+    comonads-fd          >= 3.0     && < 3.1,
     containers           >= 0.3     && < 0.6,
     contravariant        >= 0.2.0.1 && < 0.3,
     distributive         >= 0.2.2   && < 0.3,
+    free                 >= 3.0     && < 3.1,
+    keys                 >= 3.0     && < 3.1,
     mtl                  >= 2.0.1.0 && < 2.2,
     semigroups           >= 0.8.3.1 && < 0.9,
-    semigroupoids        >= 1.3.1.2 && < 1.4,
-    transformers         >= 0.2     && < 0.4,
-    keys                 >= 2.2     && < 2.3,
-    free                 >= 2.2     && < 2.3,
-    comonad-transformers >= 2.1.1.1 && < 2.2,
-    comonads-fd          >= 2.1.1.1 && < 2.2,
-    data-lens            >= 2.0.3   && < 2.11
+    semigroupoids        >= 3.0     && < 3.1,
+    transformers         >= 0.2     && < 0.4
 
   exposed-modules:
     Data.Functor.Corepresentable
diff --git a/src/Control/Comonad/Representable/Store.hs b/src/Control/Comonad/Representable/Store.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Comonad/Representable/Store.hs
@@ -0,0 +1,121 @@
+{-# LANGUAGE TypeFamilies
+           , FlexibleContexts
+           , FlexibleInstances
+           , MultiParamTypeClasses
+           , UndecidableInstances #-}
+----------------------------------------------------------------------
+-- |
+-- Module      :  Control.Comonad.Representable.Store
+-- Copyright   :  (c) Edward Kmett & Sjoerd Visscher 2011
+-- License     :  BSD3
+--
+-- Maintainer  :  ekmett@gmail.com
+-- Stability   :  experimental
+--
+-- A generalized Store comonad, parameterized by a Representable functor.
+-- The representation of that functor serves as the index of the store.
+----------------------------------------------------------------------
+module Control.Comonad.Representable.Store
+   ( Store
+   , store
+   , runStore
+   , StoreT(..)
+   , storeT
+   , runStoreT
+   , pos
+   , peek
+   , peeks
+   , seek
+   , seeks
+   ) where
+
+import Control.Comonad
+import Control.Applicative
+import Data.Key
+import Data.Functor.Apply
+import Data.Functor.Extend
+import Data.Semigroup
+import Control.Comonad.Hoist.Class
+import Control.Comonad.Env.Class
+import Control.Comonad.Traced.Class
+import Control.Comonad.Cofree.Class
+import Control.Comonad.Trans.Class
+import Control.Comonad.Store.Class
+import Control.Monad.Identity
+import Data.Functor.Representable
+
+-- | A memoized store comonad parameterized by a representable functor @g@, where
+-- the representatation of @g@, @Key g@ is the index of the store.
+--
+type Store g = StoreT g Identity
+
+-- | Construct a store comonad computation from a function and a current index.
+-- (The inverse of 'runStore'.)
+store :: Representable g
+      => (Key g -> a)  -- ^ computation
+      -> Key g         -- ^ index
+      -> Store g a
+store = storeT . Identity
+
+-- | Unwrap a state monad computation as a function.
+-- (The inverse of 'state'.)
+runStore :: Indexable g
+         => Store g a           -- ^ a store to access
+         -> (Key g -> a, Key g) -- ^ initial state
+runStore (StoreT (Identity ga) k) = (index ga, k)
+
+-- ---------------------------------------------------------------------------
+-- | A store transformer comonad parameterized by:
+--
+--   * @g@ - A representable functor used to memoize results for an index @Key g@
+--
+--   * @w@ - The inner comonad.
+data StoreT g w a = StoreT (w (g a)) (Key g)
+
+storeT :: (Functor w, Representable g) => w (Key g -> a) -> Key g -> StoreT g w a
+storeT = StoreT . fmap tabulate
+
+runStoreT :: (Functor w, Indexable g) => StoreT g w a -> (w (Key g -> a), Key g)
+runStoreT (StoreT w s) = (index <$> w, s)
+
+instance (Comonad w, Representable g, Key g ~ s) => ComonadStore s (StoreT g w) where
+  pos (StoreT _ s) = s
+  peek s (StoreT w _) = extract w `index` s
+  peeks f (StoreT w s) = extract w `index` f s
+  seek s (StoreT w _) = StoreT w s
+  seeks f (StoreT w s) = StoreT w (f s)
+
+instance (Functor w, Functor g) => Functor (StoreT g w) where
+  fmap f (StoreT w s) = StoreT (fmap (fmap f) w) s
+
+instance (Apply w, Semigroup (Key g), Representable g) => Apply (StoreT g w) where
+  StoreT ff m <.> StoreT fa n = StoreT (apRep <$> ff <.> fa) (m <> n)
+
+instance (ComonadApply w, Semigroup (Key g), Representable g) => ComonadApply (StoreT g w) where
+  StoreT ff m <@> StoreT fa n = StoreT (apRep <$> ff <@> fa) (m <> n)
+
+instance (Applicative w, Semigroup (Key g), Monoid (Key g), Representable g) => Applicative (StoreT g w) where
+  pure a = StoreT (pure (pureRep a)) mempty
+  StoreT ff m <*> StoreT fa n = StoreT (apRep <$> ff <*> fa) (m `mappend` n)
+
+instance (Extend w, Representable g) => Extend (StoreT g w) where
+  duplicated (StoreT wf s) = StoreT (extended (tabulate . StoreT) wf) s
+
+instance (Comonad w, Representable g) => Comonad (StoreT g w) where
+  duplicate (StoreT wf s) = StoreT (extend (tabulate . StoreT) wf) s
+  extract (StoreT wf s) = index (extract wf) s
+
+instance Indexable g => ComonadTrans (StoreT g) where
+  lower (StoreT w s) = fmap (`index` s) w
+
+instance ComonadHoist (StoreT g) where
+  cohoist (StoreT w s) = StoreT (Identity (extract w)) s
+
+instance (ComonadTraced m w, Representable g) => ComonadTraced m (StoreT g w) where
+  trace m = trace m . lower
+
+instance (ComonadEnv m w, Representable g) => ComonadEnv m (StoreT g w) where
+  ask = ask . lower
+
+instance (Representable g, ComonadCofree f w) => ComonadCofree f (StoreT g w) where
+  unwrap (StoreT w s) = fmap (`StoreT` s) (unwrap w)
diff --git a/src/Control/Monad/Representable/Reader.hs b/src/Control/Monad/Representable/Reader.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Representable/Reader.hs
@@ -0,0 +1,160 @@
+{-# LANGUAGE GADTs, TypeFamilies, TypeOperators, CPP, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, TypeSynonymInstances #-}
+{-# OPTIONS_GHC -fenable-rewrite-rules -fno-warn-orphans #-}
+----------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Representable.Reader
+-- Copyright   :  (c) Edward Kmett 2011,
+--                (c) Conal Elliott 2008
+-- License     :  BSD3
+--
+-- Maintainer  :  ekmett@gmail.com
+-- Stability   :  experimental
+--
+-- Representable functors on Hask all monads, being isomorphic to
+-- a reader monad.
+----------------------------------------------------------------------
+
+module Control.Monad.Representable.Reader
+  (
+  -- * Representable functor monad
+    Reader, runReader
+  -- * Monad Transformer
+  , ReaderT(..), readerT, runReaderT
+  , ask
+  , local
+  , module Data.Functor.Representable
+  ) where
+
+import Control.Applicative
+import Control.Comonad
+import Control.Monad.Reader.Class
+import Control.Monad.Writer.Class as Writer
+import Control.Monad.Trans.Class
+import Control.Monad.IO.Class
+import Data.Distributive
+import Data.Key
+import Data.Functor.Bind
+import Data.Functor.Extend
+import Data.Functor.Identity
+import Data.Functor.Representable
+import Data.Foldable
+import Data.Traversable
+import Data.Semigroup
+import Data.Semigroup.Foldable
+import Data.Semigroup.Traversable
+import Prelude hiding (lookup,zipWith)
+
+type Reader f = ReaderT f Identity
+
+runReader :: Indexable f => Reader f b -> Key f -> b
+runReader = fmap runIdentity . runReaderT
+
+-- * This 'representable monad transformer' transforms any monad @m@ with a 'Representable' 'Monad'.
+--   This monad in turn is also representable if @m@ is 'Representable'.
+newtype ReaderT f m b = ReaderT { getReaderT :: f (m b) }
+
+readerT :: Representable f => (Key f -> m b) -> ReaderT f m b
+readerT = ReaderT . tabulate
+
+runReaderT :: Indexable f => ReaderT f m b -> Key f -> m b
+runReaderT = index . getReaderT
+
+type instance Key (ReaderT f m) = (Key f, Key m)
+
+instance (Functor f, Functor m) => Functor (ReaderT f m) where
+  fmap f = ReaderT . fmap (fmap f) . getReaderT
+
+instance (Indexable f, Indexable m) => Indexable (ReaderT f m) where
+  index = uncurry . fmap index . index . getReaderT
+
+instance (Representable f, Representable m) => Representable (ReaderT f m) where
+  tabulate = ReaderT . tabulate . fmap tabulate . curry
+
+instance (Representable f, Apply m) => Apply (ReaderT f m) where
+  ReaderT ff <.> ReaderT fa = ReaderT (unrep ((<.>) <$> Rep ff <.> Rep fa))
+
+instance (Representable f, Applicative m) => Applicative (ReaderT f m) where
+  pure = ReaderT . pureRep . pure
+  ReaderT ff <*> ReaderT fa = ReaderT (unrep ((<*>) <$> Rep ff <*> Rep fa))
+
+instance (Representable f, Bind m) => Bind (ReaderT f m) where
+  ReaderT fm >>- f = ReaderT $ tabulate (\a -> index fm a >>- flip index a . getReaderT . f)
+
+instance (Representable f, Monad m) => Monad (ReaderT f m) where
+  return = ReaderT . pureRep . return
+  ReaderT fm >>= f = ReaderT $ tabulate (\a -> index fm a >>= flip index a . getReaderT . f)
+
+#if __GLASGOW_HASKELL >= 704
+
+instance (Representable f, Monad m, Key f ~ e) => MonadReader e (ReaderT f m) where
+  ask = ReaderT (tabulate return)
+  local f m = readerT $ \r -> runReaderT m (f r)
+#if MIN_VERSION_transformers(0,3,0)
+  reader = readerT . fmap return
+#endif
+
+#endif
+
+instance Representable f => MonadTrans (ReaderT f) where
+  lift = ReaderT . pureRep
+
+instance (Representable f, Distributive m) => Distributive (ReaderT f m) where
+  distribute = ReaderT . fmapRep distribute . unrep . collect (Rep . getReaderT)
+
+instance (Representable f, Keyed m) => Keyed (ReaderT f m) where
+  mapWithKey f = ReaderT . mapWithKeyRep (\k -> mapWithKey (f . (,) k)) . getReaderT
+
+instance (Indexable f, Lookup m) => Lookup (ReaderT f m) where
+  lookup (k,k') (ReaderT fm) = lookup k' (index fm k)
+
+instance (Representable f, Representable m, Semigroup (Key f), Semigroup (Key m)) => Extend (ReaderT f m) where
+  extended = extendedRep
+  duplicated = duplicatedRep
+
+instance (Representable f, Zip m) => Zip (ReaderT f m) where
+  zipWith f (ReaderT as) (ReaderT bs) = ReaderT $ tabulate $ \i -> zipWith f (index as i) (index bs i)
+
+instance (Representable f, ZipWithKey m) => ZipWithKey (ReaderT f m) where
+  zipWithKey f (ReaderT as) (ReaderT bs) = ReaderT $ tabulate $ \i -> zipWithKey (f . (,) i) (index as i) (index bs i)
+
+instance (Representable f, Representable m, Monoid (Key f), Monoid (Key m)) => Comonad (ReaderT f m) where
+  extend = extendRep
+  duplicate = duplicateRep
+  extract = extractRep
+
+instance (Representable f, MonadIO m) => MonadIO (ReaderT f m) where
+  liftIO = lift . liftIO
+
+instance (Representable f, MonadWriter w m) => MonadWriter w (ReaderT f m) where
+  tell = lift . tell
+  listen (ReaderT m) = ReaderT $ tabulate $ Writer.listen . index m
+  pass (ReaderT m) = ReaderT $ tabulate $ Writer.pass . index m
+
+-- misc. instances that can exist, but aren't particularly about representability
+
+instance (Adjustable f, Adjustable m) => Adjustable (ReaderT f m) where
+  adjust f (kf,km) = ReaderT . adjust (adjust f km) kf . getReaderT
+
+instance (Foldable f, Foldable m) => Foldable (ReaderT f m) where
+  foldMap f = foldMap (foldMap f) . getReaderT
+
+instance (Foldable1 f, Foldable1 m) => Foldable1 (ReaderT f m) where
+  foldMap1 f = foldMap1 (foldMap1 f) . getReaderT
+
+instance (FoldableWithKey f, FoldableWithKey m) => FoldableWithKey (ReaderT f m) where
+  foldMapWithKey f = foldMapWithKey (\k -> foldMapWithKey (f . (,) k)) . getReaderT
+
+instance (FoldableWithKey1 f, FoldableWithKey1 m) => FoldableWithKey1 (ReaderT f m) where
+  foldMapWithKey1 f = foldMapWithKey1 (\k -> foldMapWithKey1 (f . (,) k)) . getReaderT
+
+instance (Traversable f, Traversable m) => Traversable (ReaderT f m) where
+  traverse f = fmap ReaderT . traverse (traverse f) . getReaderT
+
+instance (Traversable1 f, Traversable1 m) => Traversable1 (ReaderT f m) where
+  traverse1 f = fmap ReaderT . traverse1 (traverse1 f) . getReaderT
+
+instance (Representable f, TraversableWithKey f, TraversableWithKey m) => TraversableWithKey (ReaderT f m) where
+  traverseWithKey f = fmap ReaderT . traverseWithKey (\k -> traverseWithKey (f . (,) k)) . getReaderT
+
+instance (Representable f, TraversableWithKey1 f, TraversableWithKey1 m) => TraversableWithKey1 (ReaderT f m) where
+  traverseWithKey1 f = fmap ReaderT . traverseWithKey1 (\k -> traverseWithKey1 (f . (,) k)) . getReaderT
diff --git a/src/Control/Monad/Representable/State.hs b/src/Control/Monad/Representable/State.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Representable/State.hs
@@ -0,0 +1,218 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances #-}
+----------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Representable.State
+-- Copyright   :  (c) Edward Kmett & Sjoerd Visscher 2011
+-- License     :  BSD3
+--
+-- Maintainer  :  ekmett@gmail.com
+-- Stability   :  experimental
+--
+-- A generalized State monad, parameterized by a Representable functor.
+-- The representation of that functor serves as the state.
+----------------------------------------------------------------------
+module Control.Monad.Representable.State
+   ( State
+   , runState
+   , evalState
+   , execState
+   , mapState
+   , StateT(..)
+   , stateT
+   , runStateT
+   , evalStateT
+   , execStateT
+   , mapStateT
+   , liftCallCC
+   , liftCallCC'
+   , get
+   , gets
+   , put
+   , modify
+   ) where
+
+import Control.Applicative
+import Data.Key
+import Data.Functor.Bind
+import Data.Functor.Bind.Trans
+import Control.Monad.State.Class
+import Control.Monad.Cont.Class
+import Control.Monad.Reader.Class
+import Control.Monad.Writer.Class
+import Control.Monad.Free.Class
+import Control.Monad.Trans.Class
+import Control.Monad.Identity
+import Data.Functor.Representable
+
+-- ---------------------------------------------------------------------------
+-- | A memoized state monad parameterized by a representable functor @g@, where
+-- the representatation of @g@, @Key g@ is the state to carry.
+--
+-- The 'return' function leaves the state unchanged, while @>>=@ uses
+-- the final state of the first computation as the initial state of
+-- the second.
+type State g = StateT g Identity
+
+
+-- | Unwrap a state monad computation as a function.
+-- (The inverse of 'state'.)
+runState :: Indexable g
+         => State g a   -- ^ state-passing computation to execute
+         -> Key g       -- ^ initial state
+         -> (a, Key g)  -- ^ return value and final state
+runState m = runIdentity . runStateT m
+
+-- | Evaluate a state computation with the given initial state
+-- and return the final value, discarding the final state.
+--
+-- * @'evalState' m s = 'fst' ('runState' m s)@
+evalState :: Indexable g
+          => State g a  -- ^state-passing computation to execute
+          -> Key g      -- ^initial value
+          -> a          -- ^return value of the state computation
+evalState m s = fst (runState m s)
+
+-- | Evaluate a state computation with the given initial state
+-- and return the final state, discarding the final value.
+--
+-- * @'execState' m s = 'snd' ('runState' m s)@
+execState :: Indexable g
+          => State g a  -- ^state-passing computation to execute
+          -> Key g      -- ^initial value
+          -> Key g      -- ^final state
+execState m s = snd (runState m s)
+
+-- | Map both the return value and final state of a computation using
+-- the given function.
+--
+-- * @'runState' ('mapState' f m) = f . 'runState' m@
+mapState :: Functor g => ((a, Key g) -> (b, Key g)) -> State g a -> State g b
+mapState f = mapStateT (Identity . f . runIdentity)
+
+-- ---------------------------------------------------------------------------
+-- | A state transformer monad parameterized by:
+--
+--   * @g@ - A representable functor used to memoize results for a state @Key g@
+--
+--   * @m@ - The inner monad.
+--
+-- The 'return' function leaves the state unchanged, while @>>=@ uses
+-- the final state of the first computation as the initial state of
+-- the second.
+newtype StateT g m a = StateT { getStateT :: g (m (a, Key g)) }
+
+stateT :: Representable g => (Key g -> m (a, Key g)) -> StateT g m a
+stateT = StateT . tabulate
+
+runStateT :: Indexable g => StateT g m a -> Key g -> m (a, Key g)
+runStateT (StateT m) = index m
+
+mapStateT :: Functor g => (m (a, Key g) -> n (b, Key g)) -> StateT g m a -> StateT g n b
+mapStateT f (StateT m) = StateT (fmap f m)
+
+-- | Evaluate a state computation with the given initial state
+-- and return the final value, discarding the final state.
+--
+-- * @'evalStateT' m s = 'liftM' 'fst' ('runStateT' m s)@
+evalStateT :: (Indexable g, Monad m) => StateT g m a -> Key g -> m a
+evalStateT m s = do
+    (a, _) <- runStateT m s
+    return a
+
+-- | Evaluate a state computation with the given initial state
+-- and return the final state, discarding the final value.
+--
+-- * @'execStateT' m s = 'liftM' 'snd' ('runStateT' m s)@
+execStateT :: (Indexable g, Monad m) => StateT g m a -> Key g -> m (Key g)
+execStateT m s = do
+    (_, s') <- runStateT m s
+    return s'
+
+instance (Functor g, Functor m) => Functor (StateT g m) where
+  fmap f = StateT . fmap (fmap (\ ~(a, s) -> (f a, s))) . getStateT
+
+instance (Functor g, Indexable g, Bind m) => Apply (StateT g m) where
+  mf <.> ma = mf >>- \f -> fmap f ma
+
+instance (Representable g, Functor m, Monad m) => Applicative (StateT g m) where
+  pure = StateT . leftAdjunctRep return
+  mf <*> ma = mf >>= \f -> fmap f ma
+
+instance (Functor g, Indexable g, Bind m) => Bind (StateT g m) where
+  StateT m >>- f = StateT $ fmap (>>- rightAdjunctRep (runStateT . f)) m
+
+instance (Representable g, Monad m) => Monad (StateT g m) where
+  return = StateT . leftAdjunctRep return
+  StateT m >>= f = StateT $ fmap (>>= rightAdjunctRep (runStateT . f)) m
+
+instance Representable f => BindTrans (StateT f) where
+  liftB m = stateT $ \s -> fmap (\a -> (a, s)) m
+
+instance Representable f => MonadTrans (StateT f) where
+  lift m = stateT $ \s -> liftM (\a -> (a, s)) m
+
+instance (Representable g, Monad m, Key g ~ s) => MonadState s (StateT g m) where
+  get = stateT $ \s -> return (s, s)
+  put s = StateT $ pureRep $ return ((),s)
+#if MIN_VERSION_transformers(0,3,0)
+  state f = stateT (return . f)
+#endif
+
+-- get :: (Representable g, Monad m) => StateT g m (Key g)
+-- put :: (Applicative g, Monad m) => Key g -> StateT g m ()
+
+-- gets :: (Representable g, Monad m) => (Key g -> s) -> StateT g m s
+-- gets f = liftM f get
+
+-- modify :: (Representable g, Monad m) => (Key g -> Key g) -> StateT g m ()
+-- modify f = stateT $ \s -> return ((), f s)
+
+instance (Representable g, MonadReader e m) => MonadReader e (StateT g m) where
+  ask = lift ask
+  local = mapStateT . local
+
+instance (Representable g, MonadWriter w m) => MonadWriter w (StateT g m) where
+  tell = lift . tell
+  listen = mapStateT $ \ma -> do
+     ((a,s'), w) <- listen ma
+     return ((a,w), s')
+  pass = mapStateT $ \ma -> pass $ do
+    ((a, f), s') <- ma
+    return ((a, s'), f)
+
+instance (Representable g, MonadCont m) => MonadCont (StateT g m) where
+    callCC = liftCallCC' callCC
+
+instance (Functor f, Representable g, MonadFree f m) => MonadFree f (StateT g m) where
+    wrap as = stateT $ \s -> wrap (fmap (`runStateT` s) as)
+
+leftAdjunctRep :: Representable u => ((a, Key u) -> b) -> a -> u b
+leftAdjunctRep f a = tabulate (\s -> f (a,s))
+
+rightAdjunctRep :: Indexable u => (a -> u b) -> (a, Key u) -> b
+rightAdjunctRep f ~(a, k) = f a `index` k
+
+-- | Uniform lifting of a @callCC@ operation to the new monad.
+-- This version rolls back to the original state on entering the
+-- continuation.
+liftCallCC :: Representable g => ((((a,Key g) -> m (b,Key g)) -> m (a,Key g)) -> m (a,Key g)) ->
+    ((a -> StateT g m b) -> StateT g m a) -> StateT g m a
+liftCallCC callCC' f = stateT $ \s ->
+    callCC' $ \c ->
+    runStateT (f (\a -> StateT $ pureRep $ c (a, s))) s
+
+-- | In-situ lifting of a @callCC@ operation to the new monad.
+-- This version uses the current state on entering the continuation.
+-- It does not satisfy the laws of a monad transformer.
+liftCallCC' :: Representable g => ((((a,Key g) -> m (b,Key g)) -> m (a,Key g)) -> m (a,Key g)) ->
+    ((a -> StateT g m b) -> StateT g m a) -> StateT g m a
+liftCallCC' callCC' f = stateT $ \s ->
+    callCC' $ \c ->
+    runStateT (f (\a -> stateT $ \s' -> c (a, s'))) s
+
diff --git a/src/Data/Functor/Corepresentable.hs b/src/Data/Functor/Corepresentable.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Corepresentable.hs
@@ -0,0 +1,122 @@
+{-# LANGUAGE TypeFamilies, FlexibleContexts, FlexibleInstances #-}
+{-# OPTIONS_GHC -fenable-rewrite-rules #-}
+
+----------------------------------------------------------------------
+-- |
+-- Module      :  Data.Functor.Corepresentable
+-- Copyright   :  (c) Edward Kmett 2011
+-- License     :  BSD3
+-- 
+-- Maintainer  :  ekmett@gmail.com
+-- Stability   :  experimental
+-- 
+-- Representable contravariant endofunctors over the category of Haskell 
+-- types are isomorphic to @(_ -> r)@ and resemble mappings to a
+-- fixed range.
+----------------------------------------------------------------------
+
+module Data.Functor.Corepresentable
+  ( 
+  -- * Values
+    Value
+  -- * Contravariant Keyed
+  , Valued(..)
+  -- * Contravariant Indexed
+  , Coindexed(..)
+  -- * Representable Contravariant Functors
+  , Corepresentable(..)
+  -- * Default definitions
+  , contramapDefault
+  , contramapWithValueDefault
+  ) where
+
+import Control.Monad.Reader
+import Data.Functor.Contravariant
+import Data.Functor.Product
+import Data.Functor.Coproduct
+import Prelude hiding (lookup)
+
+type family Value (f :: * -> *)
+
+-- | Dual to 'Keyed'.
+class Contravariant f => Valued f where
+  contramapWithValue :: (b -> Either a (Value f)) -> f a -> f b
+
+-- | Dual to 'Indexed'.
+class Coindexed f where
+  coindex :: f a -> a -> Value f
+
+-- | A 'Functor' @f@ is 'Corepresentable' if 'corep' and 'coindex' witness an isomorphism to @(_ -> Value f)@.
+--
+-- > tabulate . index = id
+-- > index . tabulate = id
+-- > tabulate . return f = return f
+
+class (Coindexed f, Valued f) => Corepresentable f where
+  -- | > contramap f (corep g) = corep (g . f)
+  corep :: (a -> Value f) -> f a
+
+{-# RULES
+"corep/coindex" forall t. corep (coindex t) = t
+ #-}
+
+-- * Default definitions
+
+contramapDefault :: Corepresentable f => (a -> b) -> f b -> f a
+contramapDefault f = corep . (. f) . coindex 
+
+contramapWithValueDefault :: Corepresentable f => (b -> Either a (Value f)) -> f a -> f b
+contramapWithValueDefault f p = corep $ either (coindex p) id . f
+
+-- * Dual arrows
+
+type instance Value (Op r) = r
+
+instance Valued (Op r) where
+  contramapWithValue = contramapWithValueDefault
+
+instance Coindexed (Op r) where
+  coindex = getOp
+
+instance Corepresentable (Op r) where
+  corep = Op
+
+-- * Predicates
+
+type instance Value Predicate = Bool
+
+instance Valued Predicate where
+  contramapWithValue = contramapWithValueDefault
+
+instance Coindexed Predicate where
+  coindex = getPredicate
+
+instance Corepresentable Predicate where
+  corep = Predicate
+
+-- * Products
+
+type instance Value (Product f g) = (Value f, Value g)
+
+instance (Valued f, Valued g) => Valued (Product f g) where
+  -- contramapWithValue :: (b -> Either a (Value f)) -> f a -> f b
+  contramapWithValue h (Pair f g) = Pair 
+      (contramapWithValue (fmap fst . h) f)
+      (contramapWithValue (fmap snd . h) g)
+      -- (contramapWithValue (either id snd . h) g)
+      -- (either g snd . h)
+
+instance (Coindexed f, Coindexed g) => Coindexed (Product f g) where
+  coindex (Pair f g) a = (coindex f a, coindex g a)
+
+instance (Corepresentable f, Corepresentable g) => Corepresentable (Product f g) where
+  corep f = Pair (corep (fst . f)) (corep (snd . f))
+
+
+-- * Coproducts
+
+type instance Value (Coproduct f g) = Either (Value f) (Value g)
+
+instance (Coindexed f, Coindexed g) => Coindexed (Coproduct f g) where
+  coindex (Coproduct (Left f)) a  = Left  $ coindex f a 
+  coindex (Coproduct (Right g)) a = Right $ coindex g a
diff --git a/src/Data/Functor/Representable.hs b/src/Data/Functor/Representable.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Representable.hs
@@ -0,0 +1,238 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# OPTIONS_GHC -fenable-rewrite-rules #-}
+----------------------------------------------------------------------
+-- |
+-- Module      :  Data.Functor.Representable
+-- Copyright   :  (c) Edward Kmett 2011
+-- License     :  BSD3
+-- 
+-- Maintainer  :  ekmett@gmail.com
+-- Stability   :  experimental
+-- 
+-- Representable endofunctors over the category of Haskell types are 
+-- isomorphic to the reader monad and so inherit a very large number
+-- of properties for free.
+----------------------------------------------------------------------
+
+module Data.Functor.Representable
+  (
+  -- * Representable Functors
+    Representable(..)
+  -- * Wrapped representable functors
+  , Rep(..)
+  -- * Default definitions
+  -- ** Functor
+  , fmapRep
+  -- ** Distributive
+  , distributeRep
+  -- ** Keyed
+  , mapWithKeyRep
+  -- ** Apply/Applicative
+  , apRep
+  , pureRep
+  , liftR2
+  , liftR3
+  -- ** Bind/Monad
+  , bindRep
+  , bindWithKeyRep
+  -- ** Zip/ZipWithKey
+  , zipWithRep
+  , zipWithKeyRep
+  -- ** MonadReader
+  , askRep
+  , localRep
+  -- ** Extend
+  , duplicatedRep
+  , extendedRep
+  -- ** Comonad
+  , duplicateRep
+  , extendRep
+  , extractRep
+  ) where
+
+import Control.Applicative
+import Control.Comonad
+import Control.Comonad.Trans.Class
+import Control.Comonad.Trans.Traced
+import Control.Comonad.Cofree
+import Control.Monad.Trans.Identity
+import Control.Monad.Reader
+import Data.Distributive
+import Data.Key
+import Data.Functor.Bind
+import Data.Functor.Identity
+import Data.Functor.Compose
+import Data.Functor.Extend
+import Data.Functor.Product
+import qualified Data.Sequence as Seq
+import Data.Semigroup hiding (Product)
+import Prelude hiding (lookup)
+
+-- | A 'Functor' @f@ is 'Representable' if 'tabulate' and 'index' witness an isomorphism to @(->) x@.
+--
+-- > tabulate . index = id
+-- > index . tabulate = id
+-- > tabulate . return f = return f
+
+class (Functor f, Indexable f) => Representable f where
+  -- | > fmap f . tabulate = tabulate . fmap f
+  tabulate :: (Key f -> a) -> f a
+
+{-# RULES
+"tabulate/index" forall t. tabulate (index t) = t
+ #-}
+
+-- * Default definitions
+
+fmapRep :: Representable f => (a -> b) -> f a -> f b
+fmapRep f = tabulate . fmap f . index
+
+mapWithKeyRep :: Representable f => (Key f -> a -> b) -> f a -> f b
+mapWithKeyRep f = tabulate . (<*>) f . index
+
+pureRep :: Representable f => a -> f a
+pureRep = tabulate . const
+
+bindRep :: Representable f => f a -> (a -> f b) -> f b
+bindRep m f = tabulate (\a -> index (f (index m a)) a)
+
+bindWithKeyRep :: Representable f => f a -> (Key f -> a -> f b) -> f b
+bindWithKeyRep m f = tabulate (\a -> index (f a (index m a)) a)
+
+askRep :: Representable f => f (Key f)
+askRep = tabulate id
+
+localRep :: Representable f => (Key f -> Key f) -> f a -> f a
+localRep f m = tabulate (index m . f)
+
+apRep :: Representable f => f (a -> b) -> f a -> f b
+apRep f g = tabulate (index f <*> index g)
+
+zipWithRep :: Representable f => (a -> b -> c) -> f a -> f b -> f c
+zipWithRep f g h = tabulate $ \k -> f (index g k) (index h k)
+
+zipWithKeyRep :: Representable f => (Key f -> a -> b -> c) -> f a -> f b -> f c
+zipWithKeyRep f g h = tabulate $ \k -> f k (index g k) (index h k)
+
+distributeRep :: (Representable f, Functor w) => w (f a) -> f (w a)
+distributeRep wf = tabulate (\k -> fmap (`index` k) wf)
+
+duplicatedRep :: (Representable f, Semigroup (Key f)) => f a -> f (f a)
+duplicatedRep w = tabulate (\m -> tabulate (index w . (<>) m))
+
+extendedRep :: (Representable f, Semigroup (Key f)) => (f a -> b) -> f a -> f b
+extendedRep f w = tabulate (\m -> f (tabulate (index w . (<>) m)))
+
+duplicateRep :: (Representable f, Monoid (Key f)) => f a -> f (f a)
+duplicateRep w = tabulate (\m -> tabulate (index w . mappend m))
+
+extendRep :: (Representable f, Monoid (Key f)) => (f a -> b) -> f a -> f b
+extendRep f w = tabulate (\m -> f (tabulate (index w . mappend m)))
+
+extractRep :: (Indexable f, Monoid (Key f)) => f a -> a
+extractRep fa = index fa mempty
+
+{-
+-- | We extend lens across a representable functor, due to the preservation of limits.
+repLens :: Representable f => Lens a b -> Lens (f a) (f b)
+repLens l = lens (fmapRep (l ^$)) $ \a b -> unrep $ liftA2 (l ^=) (Rep a) (Rep b)
+-}
+
+-- representing :: (Representable f, Functor g) => ((c -> g d) -> a -> g b) -> (f c -> g (f d)) -> f a -> g (f b)
+
+-- * Instances
+
+instance Representable Identity where
+  tabulate f = Identity (f ())
+
+instance Representable m => Representable (IdentityT m) where
+  tabulate = IdentityT . tabulate
+
+instance Representable ((->) e) where
+  tabulate = id
+
+instance Representable m => Representable (ReaderT e m) where
+  tabulate = ReaderT . fmap tabulate . curry 
+
+instance (Representable f, Representable g) => Representable (Compose f g) where
+  tabulate = Compose . tabulate . fmap tabulate . curry
+
+instance Representable w => Representable (TracedT s w) where
+  -- tabulate = TracedT . collect tabulate . curry
+  tabulate = TracedT . unrep . collect (Rep . tabulate) . curry
+
+instance (Representable f, Representable g) => Representable (Product f g) where
+  tabulate f = Pair (tabulate (f . Left)) (tabulate (f . Right))
+
+instance Representable f => Representable (Cofree f) where
+  tabulate f = f Seq.empty :< tabulate (\k -> tabulate (f . (k Seq.<|)))
+
+
+newtype Rep f a = Rep { unrep :: f a }
+
+type instance Key (Rep f) = Key f
+
+instance Representable f => Representable (Rep f) where
+  tabulate = Rep . tabulate
+
+instance Indexable f => Indexable (Rep f) where
+  index (Rep f) i = index f i
+
+instance Representable f => Keyed (Rep f) where
+  mapWithKey = mapWithKeyRep
+
+instance Indexable f => Lookup (Rep f) where
+  lookup = lookupDefault
+
+instance Representable f => Functor (Rep f) where
+  fmap = fmapRep
+
+instance Representable f => Apply (Rep f) where
+  (<.>) = apRep
+
+instance Representable f => Applicative (Rep f) where
+  pure = pureRep
+  (<*>) = apRep
+
+instance Representable f => Distributive (Rep f) where
+  distribute = distributeRep
+
+instance Representable f => Bind (Rep f) where
+  (>>-) = bindRep
+
+instance Representable f => Monad (Rep f) where
+  return = pureRep
+  (>>=) = bindRep
+
+#if __GLASGOW_HASKELL__ >= 704
+instance (Representable f, Key f ~ a) => MonadReader a (Rep f) where
+  ask = askRep
+  local = localRep
+#endif
+
+instance Representable f => Zip (Rep f) where
+  zipWith = zipWithRep
+
+instance Representable f => ZipWithKey (Rep f) where
+  zipWithKey = zipWithKeyRep
+
+instance (Representable f, Semigroup (Key f)) => Extend (Rep f) where
+  extended = extendedRep
+
+instance (Representable f, Monoid (Key f)) => Comonad (Rep f) where
+  extend = extendRep
+  extract = extractRep
+
+instance ComonadTrans Rep where
+  lower (Rep f) = f
+
+liftR2 :: Representable f => (a -> b -> c) -> f a -> f b -> f c
+liftR2 f fa fb = tabulate $ \i -> f (index fa i) (index fb i)
+
+liftR3 :: Representable f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
+liftR3 f fa fb fc = tabulate $ \i -> f (index fa i) (index fb i) (index fc i)
