diff --git a/Control/Monad/Representable.hs b/Control/Monad/Representable.hs
--- a/Control/Monad/Representable.hs
+++ b/Control/Monad/Representable.hs
@@ -83,7 +83,7 @@
 instance (Keyed f, Keyed m) => Keyed (RepT f m) where
   mapWithKey f = RepT . mapWithKey (\k -> mapWithKey (f . (,) k)) . runRepT
 
-instance (Index f, Index m) => Index (RepT f m) where
+instance (Indexable f, Indexable m) => Indexable (RepT f m) where
   index = uncurry . fmap index . index . runRepT
 
 instance (Lookup f, Lookup m) => Lookup (RepT f m) where
diff --git a/Data/Functor/Corepresentable.hs b/Data/Functor/Corepresentable.hs
new file mode 100644
--- /dev/null
+++ b/Data/Functor/Corepresentable.hs
@@ -0,0 +1,121 @@
+{-# 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
+  ( 
+    Value -- ^ a contravariant version of Key
+  -- * 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
--- a/Data/Functor/Representable.hs
+++ b/Data/Functor/Representable.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE TypeFamilies, FlexibleContexts, FlexibleInstances #-}
-{-# OPTIONS_GHC -fenable-rewrite-rules -fno-warn-orphans #-}
+{-# OPTIONS_GHC -fenable-rewrite-rules #-}
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Data.Functor.Representable
@@ -50,7 +50,8 @@
 import Data.Functor.Bind
 import Data.Functor.Identity
 import Data.Functor.Compose
-import Data.Monoid
+import Data.Functor.Product
+import Data.Monoid hiding (Product)
 import Prelude hiding (lookup)
 
 -- | A 'Functor' @f@ is 'Representable' if 'tabulate' and 'index' witness an isomorphism to @(->) x@.
@@ -59,7 +60,7 @@
 -- > index . tabulate = id
 -- > tabulate . return f = return f
 
-class (Index f, Distributive f, Keyed f, Apply f, Applicative f {- , Bind f, Monad f -}) => Representable f where
+class (Indexable f, Distributive f, Keyed f, Apply f, Applicative f) => Representable f where
   -- | > fmap f . tabulate = tabulate . fmap f
   tabulate :: (Key f -> a) -> f a
 
@@ -102,7 +103,7 @@
 extendRep :: (Representable f, Semigroup (Key f)) => (f a -> b) -> f a -> f b
 extendRep f w = tabulate (\m -> f (tabulate (index w . (<>) m)))
 
-extractRep :: (Index f, Monoid (Key f)) => f a -> a
+extractRep :: (Indexable f, Monoid (Key f)) => f a -> a
 extractRep fa = index fa mempty
 
 -- * Instances
@@ -125,21 +126,6 @@
 instance Representable w => Representable (TracedT s w) where
   tabulate = TracedT . collect tabulate . curry
 
-
-{-
--- * Orphans
-instance (Representable f, Bind m) => Bind (Compose f m) where
-  Compose fm >>- f = Compose $ tabulate (\a -> index fm a >>- flip index a . getCompose . f)
-
-instance Representable w => Monad (TracedT s w) where
-  return = TracedT . pure . pure
-  TracedT fm >>= f = TracedT $ tabulate (\a -> index fm a >>= flip index a . runTracedT . f)
-
-instance Representable w => Bind (TracedT s w) where
-  TracedT fm >>- f = TracedT $ tabulate (\a -> index fm a >>- flip index a . runTracedT . f)
-  
-instance (Representable f, Monad m) => Monad (Compose f m) where
-  return = Compose . pure . return
-  Compose fm >>= f = Compose $ tabulate (\a -> index fm a >>= flip index a . getCompose . f)
--}
+instance (Representable f, Representable g) => Representable (Product f g) where
+  tabulate f = Pair (tabulate (f . Left)) (tabulate (f . Right))
 
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:       0.2.0
+version:       0.3.0
 license:       BSD3
 cabal-version: >= 1.6
 license-file:  LICENSE
@@ -26,13 +26,14 @@
     containers >= 0.4 && < 0.5,
     contravariant >= 0.1.2 && < 0.2,
     distributive >= 0.1.1 && < 0.2,
-    keys >= 0.1.0.1 && < 0.2,
+    keys >= 0.2 && < 0.3,
     mtl >= 2.0.1.0 && < 2.1,
     semigroups >= 0.3.4 && < 0.4,
     semigroupoids >= 1.1.1 && < 1.2.0,
     transformers >= 0.2.0 && < 0.3
 
   exposed-modules:
+    Data.Functor.Corepresentable
     Data.Functor.Representable
     Control.Monad.Representable
 
