diff --git a/Data/Key.hs b/Data/Key.hs
new file mode 100644
--- /dev/null
+++ b/Data/Key.hs
@@ -0,0 +1,508 @@
+{-# LANGUAGE TypeFamilies #-}
+module Data.Key (
+  -- * Keys
+    Key
+
+  -- * Keyed functors
+  , Keyed(..)
+  , (<#$>) -- :: Keyed f => (Key f -> a -> b) -> f a -> f b
+  , keyed -- :: Keyed f => f a -> f (Key f, a)
+  , apWithKey
+
+  -- * Indexing
+  , Index(..)
+  , (!)
+
+  -- * Safe Lookup
+  , Lookup(..)
+  , lookupDefault
+
+  -- * FoldableWithKey
+  , FoldableWithKey(..)
+  , foldrWithKey' -- :: FoldableWithKey t => (Key t -> a -> b -> b) -> b -> t a -> b
+  , foldlWithKey' -- :: FoldableWithKey t => (b -> Key t -> a -> b) -> b -> t a -> b
+  , foldrWithKeyM -- :: (FoldableWithKey t, Monad m) => (Key t -> a -> b -> m b) -> b -> t a -> m b
+  , foldlWithKeyM -- :: (FoldableWithKey t, Monad m) => (b -> Key t -> a -> m b) -> b -> t a -> m b
+  , traverseWithKey_ -- :: (FoldableWithKey t, Applicative f) => (Key t -> a -> f b) -> t a -> f ()
+  , forWithKey_ -- :: (FoldableWithKey t, Applicative f) => t a -> (Key t -> a -> f b) -> f ()
+  , mapWithKeyM_ -- :: (FoldableWithKey t, Monad m) => (Key t -> a -> m b) -> t a -> m ()
+  , forWithKeyM_ -- :: (FoldableWithKey t, Monad m) => t a -> (Key t -> a -> m b) -> m ()
+  , concatMapWithKey -- :: FoldableWithKey t => (Key t -> a -> [b]) -> t a -> [b]
+  , anyWithKey -- :: FoldableWithKey t => (Key t -> a -> Bool) -> t a -> Bool
+  , allWithKey -- :: FoldableWithKey t => (Key t -> a -> Bool) -> t a -> Bool
+  , findWithKey -- :: FoldableWithKey t => (Key t -> a -> Bool) -> t a -> Maybe a
+
+  -- * FoldableWithKey1
+  , FoldableWithKey1(..)
+  , traverseWithKey1_ -- :: (FoldableWithKey1 t, Apply f) => (Key t -> a -> f b) -> t a -> f ()
+  , forWithKey1_ -- :: (FoldableWithKey1 t, Apply f) => t a -> (Key t -> a -> f b) -> f ()
+  , foldMapWithKeyDefault1 -- :: (FoldableWithKey1, Monoid m) => (Key t -> a -> m) -> t a -> m
+
+  -- * TraversableWithKey
+  , TraversableWithKey(..)
+  , forWithKey -- :: (TraversableWithKey t, Applicative f) => t a -> (Key t -> a -> f b) -> f (t b)
+  , forWithKeyM -- :: (TraversableWithKey t, Monad m) => t a -> (Key t -> a -> m b) -> m (t b)
+  , mapAccumWithKeyL -- :: TraversableWithKey t => (Key t -> a -> b -> (a, c)) -> t a -> (a, t c)
+  , mapAccumWithKeyR -- :: TraversableWithKey t => (Key t -> a -> b -> (a, c)) -> t a -> (a, t c)
+  , mapWithKeyDefault -- :: TraversableWithKey t => (Key t -> a -> b) -> t a -> t b
+  , foldMapWithKeyDefault -- :: (TraversableWithKey t, Monoid m) => (Key t -> a -> m) -> t a -> m
+
+  -- * TraverableWithKey1
+  , TraversableWithKey1(..)
+  , foldMapWithKey1Default -- :: (TraversableWithKey1 t, Semigroup m) => (Key t -> a -> m) -> t a -> m
+  , module Data.Foldable
+  , module Data.Traversable
+  , module Data.Semigroup
+  , module Data.Semigroup.Foldable
+  , module Data.Semigroup.Traversable
+  ) where
+
+import Control.Applicative
+import Control.Comonad.Trans.Traced
+import Control.Monad.Trans.Identity
+import Control.Monad.Trans.Reader
+import qualified Data.Array as Array
+import Data.Array (Array)
+-- import qualified Data.Array.IArray as IArray
+-- import qualified Data.Array.Unboxed hiding (index)
+-- import Data.Array.Unboxed (UArray)
+import Data.Functor.Identity
+import Data.Functor.Bind
+import Data.Functor.Compose
+import Data.Foldable
+import Data.IntMap (IntMap)
+import qualified Data.IntMap as IntMap
+import Data.Ix hiding (index)
+import Data.Map (Map)
+import qualified Data.Map as Map
+import Data.Maybe (listToMaybe)
+import Data.Monoid as Monoid
+import Data.Semigroup
+import Data.Semigroup.Foldable
+import Data.Semigroup.Traversable
+import Data.Sequence (Seq, ViewL(..), viewl)
+import qualified Data.Sequence as Seq
+import Data.Traversable
+import Prelude hiding (lookup)
+
+type family Key (f :: * -> *) 
+
+-- * Keyed
+class Functor f => Keyed f where
+  mapWithKey :: (Key f -> a -> b) -> f a -> f b
+
+infixl 4 <#$>
+
+(<#$>) :: Keyed f => (Key f -> a -> b) -> f a -> f b
+(<#$>) = mapWithKey
+{-# INLINE (<#$>) #-}
+
+keyed :: Keyed f => f a -> f (Key f, a)
+keyed = mapWithKey (,)
+{-# INLINE keyed #-}
+
+apWithKey :: (Keyed f, Applicative f) => f (Key f -> a -> b) -> f a -> f b
+apWithKey ff fa = mapWithKey (\k f -> f k) ff <*> fa
+{-# INLINE apWithKey #-}
+
+-- * Index
+
+class Index f where
+  index :: f a -> Key f -> a
+
+(!) :: Index f => f a -> Key f -> a
+(!) = index
+
+-- * Lookup
+
+class Lookup f where
+  lookup :: Key f -> f a -> Maybe a
+
+lookupDefault :: Index f => Key f -> f a -> Maybe a
+lookupDefault k t = Just (index t k)
+
+-- * FoldableWithKey
+
+class Foldable t => FoldableWithKey t where
+  toIndexedList :: t a -> [(Key t, a)]
+  toIndexedList = foldrWithKey (\k v t -> (k,v):t) []
+
+  foldMapWithKey :: Monoid m => (Key t -> a -> m) -> t a -> m
+  foldMapWithKey f = foldrWithKey (\k v -> mappend (f k v)) mempty
+
+  foldrWithKey :: (Key t -> a -> b -> b) -> b -> t a -> b
+  foldrWithKey f z t = appEndo (foldMapWithKey (\k v -> Endo (f k v)) t) z
+
+  foldlWithKey :: (b -> Key t -> a -> b) -> b -> t a -> b
+  foldlWithKey f z t = appEndo (getDual (foldMapWithKey (\k a -> Dual (Endo (\b -> f b k a))) t)) z
+
+foldrWithKey' :: FoldableWithKey t => (Key t -> a -> b -> b) -> b -> t a -> b
+foldrWithKey' f z0 xs = foldlWithKey f' id xs z0
+  where f' k key x z = k $! f key x z
+{-# INLINE foldrWithKey' #-}
+
+foldlWithKey' :: FoldableWithKey t => (b -> Key t -> a -> b) -> b -> t a -> b
+foldlWithKey' f z0 xs = foldrWithKey f' id xs z0
+  where f' key x k z = k $! f z key x
+{-# INLINE foldlWithKey' #-}
+
+foldrWithKeyM :: (FoldableWithKey t, Monad m) => (Key t -> a -> b -> m b) -> b -> t a -> m b
+foldrWithKeyM f z0 xs = foldlWithKey f' return xs z0
+  where f' k key x z = f key x z >>= k
+{-# INLINE foldrWithKeyM #-}
+
+foldlWithKeyM :: (FoldableWithKey t, Monad m) => (b -> Key t -> a -> m b) -> b -> t a -> m b
+foldlWithKeyM f z0 xs = foldrWithKey f' return xs z0
+  where f' key x k z = f z key x >>= k
+{-# INLINE foldlWithKeyM #-}
+
+traverseWithKey_ :: (FoldableWithKey t, Applicative f) => (Key t -> a -> f b) -> t a -> f ()
+traverseWithKey_ f = foldrWithKey (fmap (*>) . f) (pure ())
+{-# INLINE traverseWithKey_ #-}
+
+forWithKey_ :: (FoldableWithKey t, Applicative f) => t a -> (Key t -> a -> f b) -> f ()
+forWithKey_ = flip traverseWithKey_
+{-# INLINE forWithKey_ #-}
+
+mapWithKeyM_ :: (FoldableWithKey t, Monad m) => (Key t -> a -> m b) -> t a -> m ()
+mapWithKeyM_ f = foldrWithKey (fmap (>>) . f) (return ())
+{-# INLINE mapWithKeyM_ #-}
+
+forWithKeyM_ :: (FoldableWithKey t, Monad m) => t a -> (Key t -> a -> m b) -> m ()
+forWithKeyM_ = flip mapWithKeyM_
+{-# INLINE forWithKeyM_ #-}
+
+concatMapWithKey :: FoldableWithKey t => (Key t -> a -> [b]) -> t a -> [b]
+concatMapWithKey = foldMapWithKey
+{-# INLINE concatMapWithKey #-}
+
+anyWithKey :: FoldableWithKey t => (Key t -> a -> Bool) -> t a -> Bool
+anyWithKey p = getAny . foldMapWithKey (fmap Any . p)
+{-# INLINE anyWithKey #-}
+
+allWithKey :: FoldableWithKey t => (Key t -> a -> Bool) -> t a -> Bool
+allWithKey p = getAll . foldMapWithKey (fmap All . p)
+{-# INLINE allWithKey #-}
+
+findWithKey :: FoldableWithKey t => (Key t -> a -> Bool) -> t a -> Maybe a
+findWithKey p = Monoid.getFirst . foldMapWithKey (\k x -> Monoid.First (if p k x then Just x else Nothing) )
+{-# INLINE findWithKey #-}
+
+-- * FoldableWithKey1
+
+class (Foldable1 t, FoldableWithKey t) => FoldableWithKey1 t where
+  foldMapWithKey1 :: Semigroup m => (Key t -> a -> m) -> t a -> m
+
+newtype Act f a = Act { getAct :: f a }
+
+instance Apply f => Semigroup (Act f a) where
+  Act a <> Act b = Act (a .> b)
+
+instance Functor f => Functor (Act f) where
+  fmap f (Act a) = Act (f <$> a)
+  b <$ Act a = Act (b <$ a)
+
+traverseWithKey1_ :: (FoldableWithKey1 t, Apply f) => (Key t -> a -> f b) -> t a -> f ()
+traverseWithKey1_ f = (<$) () . getAct . foldMapWithKey1 (fmap Act . f)
+{-# INLINE traverseWithKey1_ #-}
+
+forWithKey1_ :: (FoldableWithKey1 t, Apply f) => t a -> (Key t -> a -> f b) -> f ()
+forWithKey1_ = flip traverseWithKey1_
+{-# INLINE forWithKey1_ #-}
+
+foldMapWithKeyDefault1 :: (FoldableWithKey1 t, Monoid m) => (Key t -> a -> m) -> t a -> m
+foldMapWithKeyDefault1 f = unwrapMonoid . foldMapWithKey (fmap WrapMonoid . f)
+{-# INLINE foldMapWithKeyDefault1 #-}
+
+-- * TraversableWithKey
+
+class (Keyed t, FoldableWithKey t, Traversable t) => TraversableWithKey t where
+  traverseWithKey :: Applicative f => (Key t -> a -> f b) -> t a -> f (t b)
+
+  mapWithKeyM :: Monad m => (Key t -> a -> m b) -> t a -> m (t b)
+  mapWithKeyM f = unwrapMonad . traverseWithKey (fmap WrapMonad . f) 
+
+forWithKey :: (TraversableWithKey t, Applicative f) => t a -> (Key t -> a -> f b) -> f (t b)
+forWithKey = flip traverseWithKey
+{-# INLINE forWithKey #-}
+
+forWithKeyM :: (TraversableWithKey t, Monad m) => t a -> (Key t -> a -> m b) -> m (t b)
+forWithKeyM = flip mapWithKeyM
+{-# INLINE forWithKeyM #-}
+
+
+-- left-to-right state transformer
+newtype StateL s a = StateL { runStateL :: s -> (s, a) }
+
+instance Functor (StateL s) where
+  fmap f (StateL k) = StateL $ \ s ->
+    let (s', v) = k s in (s', f v)
+
+instance Applicative (StateL s) where
+  pure x = StateL (\ s -> (s, x))
+  StateL kf <*> StateL kv = StateL $ \ s ->
+    let (s', f) = kf s
+        (s'', v) = kv s'
+    in  (s'', f v)
+
+-- |The 'mapAccumWithKeyL' function behaves like a combination of 'mapWithKey'
+-- and 'foldlWithKey'; it applies a function to each element of a structure,
+-- passing an accumulating parameter from left to right, and returning
+-- a final value of this accumulator together with the new structure.
+mapAccumWithKeyL :: TraversableWithKey t => (Key t -> a -> b -> (a, c)) -> a -> t b -> (a, t c)
+mapAccumWithKeyL f s t = runStateL (traverseWithKey (\k b -> StateL (\a -> f k a b)) t) s
+{-# INLINE mapAccumWithKeyL #-}
+
+-- right-to-left state transformer
+newtype StateR s a = StateR { runStateR :: s -> (s, a) }
+
+instance Functor (StateR s) where
+  fmap f (StateR k) = StateR $ \ s ->
+    let (s', v) = k s in (s', f v)
+
+instance Applicative (StateR s) where
+  pure x = StateR (\ s -> (s, x))
+  StateR kf <*> StateR kv = StateR $ \ s ->
+    let (s', v) = kv s
+        (s'', f) = kf s'
+    in (s'', f v)
+
+-- |The 'mapAccumWithKeyR' function behaves like a combination of 'mapWithKey'
+-- and 'foldrWithKey'; it applies a function to each element of a structure,
+-- passing an accumulating parameter from right to left, and returning
+-- a final value of this accumulator together with the new structure.
+mapAccumWithKeyR :: TraversableWithKey t => (Key t -> a -> b -> (a, c)) -> a -> t b -> (a, t c)
+mapAccumWithKeyR f s t = runStateR (traverseWithKey (\k b -> StateR (\a -> f k a b)) t) s
+{-# INLINE mapAccumWithKeyR #-}
+
+mapWithKeyDefault :: TraversableWithKey t => (Key t -> a -> b) -> t a -> t b
+mapWithKeyDefault f = runIdentity . traverseWithKey (fmap Identity . f)
+{-# INLINE mapWithKeyDefault #-}
+
+-- | This function may be used as a value for `Data.Foldable.foldMapWithKey`
+-- in a `FoldableWithKey` instance.
+foldMapWithKeyDefault :: (TraversableWithKey t, Monoid m) => (Key t -> a -> m) -> t a -> m
+foldMapWithKeyDefault f = getConst . traverseWithKey (fmap Const . f)
+{-# INLINE foldMapWithKeyDefault #-}
+
+-- * TraverableWithKey1
+class (Traversable1 t, FoldableWithKey1 t, TraversableWithKey t) => TraversableWithKey1 t where
+  traverseWithKey1 :: Apply f => (Key t -> a -> f b) -> t a -> f (t b)
+
+foldMapWithKey1Default :: (TraversableWithKey1 t, Semigroup m) => (Key t -> a -> m) -> t a -> m
+foldMapWithKey1Default f = getConst . traverseWithKey1 (\k -> Const . f k)
+{-# INLINE foldMapWithKey1Default #-}
+
+-- * Instances
+
+type instance Key Identity = ()
+
+instance Index Identity where
+  index (Identity a) _ = a
+
+instance Lookup Identity where
+  lookup _ (Identity a) = Just a
+
+instance Keyed Identity where
+  mapWithKey f = Identity . f () . runIdentity
+
+instance FoldableWithKey Identity where
+  foldrWithKey f z (Identity a) = f () a z
+
+instance FoldableWithKey1 Identity where
+  foldMapWithKey1 f (Identity a) = f () a
+
+instance TraversableWithKey Identity where
+  traverseWithKey f (Identity a) = Identity <$> f () a
+
+instance TraversableWithKey1 Identity where
+  traverseWithKey1 f (Identity a) = Identity <$> f () a
+
+type instance Key (IdentityT m) = Key m
+
+instance Index m => Index (IdentityT m) where
+  index (IdentityT m) i = index m i
+
+instance Lookup m => Lookup (IdentityT m) where
+  lookup i (IdentityT m) = lookup i m
+
+instance Keyed m => Keyed (IdentityT m) where
+  mapWithKey f = IdentityT . mapWithKey f . runIdentityT 
+
+instance FoldableWithKey m => FoldableWithKey (IdentityT m) where
+  foldrWithKey f z (IdentityT m) = foldrWithKey f z m
+
+instance FoldableWithKey1 m => FoldableWithKey1 (IdentityT m) where
+  foldMapWithKey1 f (IdentityT m) = foldMapWithKey1 f m
+
+instance TraversableWithKey m => TraversableWithKey (IdentityT m) where
+  traverseWithKey f (IdentityT a) = IdentityT <$> traverseWithKey f a
+
+instance TraversableWithKey1 m => TraversableWithKey1 (IdentityT m) where
+  traverseWithKey1 f (IdentityT a) = IdentityT <$> traverseWithKey1 f a
+
+type instance Key ((->)a) = a
+
+instance Keyed ((->)a) where
+  mapWithKey = (<*>)
+
+instance Index ((->)a) where
+  index = id
+  
+instance Lookup ((->)a) where
+  lookup i f = Just (f i)
+
+type instance Key (ReaderT e m) = (e, Key m)
+
+instance Keyed m => Keyed (ReaderT e m) where
+  mapWithKey f (ReaderT m) = ReaderT $ \k -> mapWithKey (f . (,) k) (m k)
+
+instance Index m => Index (ReaderT e m) where
+  index (ReaderT f) (e,k) = index (f e) k
+
+instance Lookup m => Lookup (ReaderT e m) where
+  lookup (e,k) (ReaderT f) = lookup k (f e)
+
+type instance Key (TracedT s w) = (s, Key w)
+
+instance Keyed w => Keyed (TracedT s w) where
+  mapWithKey f = TracedT . mapWithKey (\k' g k -> f (k, k') (g k)) . runTracedT 
+
+instance Index w => Index (TracedT s w) where
+  index (TracedT w) (e,k) = index w k e 
+
+instance Lookup w => Lookup (TracedT s w) where
+  lookup (e,k) (TracedT w) = ($ e) <$> lookup k w
+  
+type instance Key IntMap = Int
+
+instance Keyed IntMap where
+  mapWithKey = IntMap.mapWithKey
+
+instance FoldableWithKey IntMap where
+  foldrWithKey = IntMap.foldWithKey
+
+instance TraversableWithKey IntMap where
+  traverseWithKey f = fmap IntMap.fromDistinctAscList . traverse (\(k, v) -> (,) k <$> f k v) . IntMap.toAscList
+
+instance Index IntMap where
+  index = (IntMap.!)
+
+instance Lookup IntMap where
+  lookup = IntMap.lookup
+
+type instance Key (Compose f g) = (Key f, Key g)
+
+instance (Keyed f, Keyed g) => Keyed (Compose f g) where
+  mapWithKey f = Compose . mapWithKey (\k -> mapWithKey (f . (,) k)) . getCompose
+
+instance (Index f, Index g) => Index (Compose f g) where
+  index (Compose fg) (i,j) = index (index fg i) j
+
+instance (Lookup f, Lookup g) => Lookup (Compose f g) where
+  lookup (i,j) (Compose fg) = lookup i fg >>= lookup j
+
+instance (FoldableWithKey f, FoldableWithKey m) => FoldableWithKey (Compose f m) where
+  foldMapWithKey f = foldMapWithKey (\k -> foldMapWithKey (f . (,) k)) . getCompose
+
+instance (FoldableWithKey1 f, FoldableWithKey1 m) => FoldableWithKey1 (Compose f m) where
+  foldMapWithKey1 f = foldMapWithKey1 (\k -> foldMapWithKey1 (f . (,) k)) . getCompose
+
+instance (TraversableWithKey f, TraversableWithKey m) => TraversableWithKey (Compose f m) where
+  traverseWithKey f = fmap Compose . traverseWithKey (\k -> traverseWithKey (f . (,) k)) . getCompose
+
+instance (TraversableWithKey1 f, TraversableWithKey1 m) => TraversableWithKey1 (Compose f m) where
+  traverseWithKey1 f = fmap Compose . traverseWithKey1 (\k -> traverseWithKey1 (f . (,) k)) . getCompose
+
+type instance Key [] = Int
+
+instance Keyed [] where
+  mapWithKey f0 xs0 = go f0 xs0 0 where
+    go _ [] _ = []
+    go f (x:xs) n = f n x : (go f xs $! n)
+
+instance FoldableWithKey [] where
+  foldrWithKey f0 z0 xs0 = go f0 z0 xs0 0 where
+    go _ z [] _ = z
+    go f z (x:xs) n = f n x (go f z xs $! n)
+
+instance TraversableWithKey [] where
+  traverseWithKey f0 xs0 = go f0 xs0 0 where
+    go _ [] _ = pure []
+    go f (x:xs) n = (:) <$> f n x <*> (go f xs $! (n + 1))
+
+instance Index [] where
+  index = (!!)
+
+instance Lookup [] where
+  lookup = fmap listToMaybe . drop
+
+type instance Key Seq = Int
+
+instance Index Seq where
+  index = Seq.index
+
+instance Lookup Seq where
+  lookup i s = case viewl (Seq.drop i s) of
+    EmptyL -> Nothing
+    a :< _ -> Just a
+
+instance Keyed Seq where
+  mapWithKey = Seq.mapWithIndex
+
+instance FoldableWithKey Seq where
+  foldrWithKey = Seq.foldrWithIndex
+
+instance TraversableWithKey Seq where
+  traverseWithKey f = fmap Seq.fromList . traverseWithKey f . toList
+
+type instance Key (Map k) = k
+
+instance Keyed (Map k) where
+  mapWithKey = Map.mapWithKey
+
+instance Ord k => Index (Map k) where
+  index = (Map.!)
+
+instance Ord k => Lookup (Map k) where
+  lookup = Map.lookup
+
+instance FoldableWithKey (Map k) where
+  foldrWithKey = Map.foldrWithKey
+
+instance TraversableWithKey (Map k) where
+  traverseWithKey f = fmap Map.fromDistinctAscList . traverse (\(k, v) -> (,) k <$> f k v) . Map.toAscList
+
+type instance Key (Array i) = i
+  
+instance Ix i => Keyed (Array i) where
+  mapWithKey f arr = Array.listArray (Array.bounds arr) $ map (uncurry f) $ Array.assocs arr
+  
+instance Ix i => Index (Array i) where
+  index = (Array.!)
+
+instance Ix i => Lookup (Array i) where
+  lookup i arr
+    | inRange (Array.bounds arr) i = Just (arr Array.! i)
+    | otherwise = Nothing
+
+instance Ix i => FoldableWithKey (Array i) where
+  foldrWithKey f z = Prelude.foldr (uncurry f) z . Array.assocs
+
+instance Ix i => TraversableWithKey (Array i) where
+  traverseWithKey f arr = Array.listArray (Array.bounds arr) <$> traverse (uncurry f) (Array.assocs arr)
+  
+{-
+type instance Key (UArray i) = i
+
+instance Ix i => Index (UArray i) where
+  index = (IArray.!)
+
+instance Ix i => Lookup (UArray i) where
+  lookup i arr
+    | inRange (IArray.bounds arr) i = Just (arr IArray.! i)
+    | otherwise = Nothing
+
+instance Ix i => FoldableWithKey (UArray i) where
+  foldrWithKey f z = Prelude.foldr (uncurry f) z . IArray.assocs
+-}
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright 2011 Edward Kmett
+
+All rights reserved.
+
+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 author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,7 @@
+#!/usr/bin/runhaskell
+> module Main (main) where
+
+> import Distribution.Simple
+
+> main :: IO ()
+> main = defaultMain
diff --git a/keys.cabal b/keys.cabal
new file mode 100644
--- /dev/null
+++ b/keys.cabal
@@ -0,0 +1,34 @@
+name:          keys
+category:      Data Structures, Containers
+version:       0.1.0
+license:       BSD3
+cabal-version: >= 1.6
+license-file:  LICENSE
+author:        Edward A. Kmett
+maintainer:    Edward A. Kmett <ekmett@gmail.com>
+stability:     provisional
+homepage:      http://github.com/ekmett/keys/
+copyright:     Copyright (C) 2011 Edward A. Kmett
+synopsis:      Keyed functors and containers
+description:   Keyed functors and containers
+build-type:    Simple
+
+source-repository head
+  type: git
+  location: git://github.com/ekmett/adjunctions.git
+
+library
+  build-depends: 
+    array >= 0.3.0.2 && < 0.4,
+    base >= 4 && < 4.4,
+    comonad-transformers >= 1.5.0.3 && < 1.6,
+    containers >= 0.4 && < 0.5,
+    semigroups >= 0.3.4 && < 0.4,
+    semigroupoids >= 1.1.1 && < 1.2,
+    transformers >= 0.2.0 && < 0.3
+
+  exposed-modules:
+    Data.Key
+
+  ghc-options: -Wall
+
