diff --git a/MemoTrie.cabal b/MemoTrie.cabal
--- a/MemoTrie.cabal
+++ b/MemoTrie.cabal
@@ -1,5 +1,5 @@
 Name:                MemoTrie
-Version:             0.6.2
+Version:             0.6.3
 Cabal-Version:       >= 1.6
 Synopsis:            Trie-based memo functions
 Category:            Data
@@ -11,7 +11,7 @@
   Project wiki page: <http://haskell.org/haskellwiki/MemoTrie>
   .
   &#169; 2008-2012 by Conal Elliott; BSD3 license.
-Homepage:            http://haskell.org/haskellwiki/MemoTrie
+Homepage:            https://github.com/conal/MemoTrie
 Author:              Conal Elliott 
 Maintainer:          conal@conal.net
 Copyright:           (c) 2008-2012 by Conal Elliott
diff --git a/src/Data/MemoTrie.hs b/src/Data/MemoTrie.hs
--- a/src/Data/MemoTrie.hs
+++ b/src/Data/MemoTrie.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE GADTs, TypeFamilies, TypeOperators, ScopedTypeVariables, CPP #-}
-{-# LANGUAGE StandaloneDeriving, FlexibleInstances #-}
+{-# LANGUAGE StandaloneDeriving, FlexibleInstances #-} 
+{-# LANGUAGE DefaultSignatures, FlexibleContexts, EmptyCase, LambdaCase #-}
 {-# OPTIONS_GHC -Wall -fenable-rewrite-rules #-}
 -- ScopedTypeVariables works around a 6.10 bug.  The forall keyword is
 -- supposed to be recognized in a RULES pragma.
@@ -18,6 +19,25 @@
 -- Adapted from sjanssen's paste: \"a lazy trie\" <http://hpaste.org/3839>,
 -- which I think is based on Ralf Hinze's paper "Memo Functions,
 -- Polytypically!".
+-- 
+-- You can automatically derive generic instances. for example: 
+-- 
+-- @
+-- -- LANGUAGE DeriveGeneric, TypeOperators  
+-- 
+-- data Color 
+--  = RGB Int Int Int
+--  | Color String 
+--  deriving (Generic) 
+-- 
+-- instance HasTrie Color where
+--  newtype (Color :->: b) = ColorTrie { unColorTrie :: 'Reg' Color :->: b } 
+--  trie = 'trieGeneric' ColorTrie 
+--  untrie = 'untrieGeneric' unColorTrie
+--  enumerate = 'enumerateGeneric' unColorTrie
+-- @
+-- 
+-- 
 ----------------------------------------------------------------------
 
 module Data.MemoTrie
@@ -27,6 +47,7 @@
   , memo, memo2, memo3, mup
   , inTrie, inTrie2, inTrie3
   -- , untrieBits
+  , trieGeneric, untrieGeneric, enumerateGeneric, Reg   
   ) where
 
 -- Export the parts of HasTrie separately in order to get the associated data
@@ -39,6 +60,7 @@
 import Control.Arrow (first,(&&&))
 import Data.Monoid
 import Data.Function (on)
+import GHC.Generics
 
 import Data.Void
 
@@ -529,4 +551,108 @@
 f1 n = n + n
 
 f1' = memo f1
+-}
+
+-- | just like @void@ 
+instance HasTrie (V1 x) where
+ data (V1 x :->: b) = V1Trie 
+ trie _ = V1Trie 
+ untrie V1Trie = \case 
+ enumerate V1Trie = [] 
+
+-- | just like @()@ 
+instance HasTrie (U1 x) where
+ data (U1 x :->: b) = U1Trie b 
+ trie f = U1Trie (f U1)
+ untrie (U1Trie b) = \U1 -> b
+ enumerate (U1Trie b) = [(U1, b)] 
+
+-- | wraps @Either (f x) (g x)@ 
+instance (HasTrie (f x), HasTrie (g x)) => HasTrie ((f :+: g) x) where
+ newtype ((f :+: g) x :->: b) = EitherTrie1 (Either (f x) (g x) :->: b)
+ trie f = EitherTrie1 (trie (f . liftSum))
+ untrie (EitherTrie1 t) = (untrie t) . dropSum
+ enumerate (EitherTrie1 t) = enum' liftSum t
+
+-- | wraps @(f x, g x)@ 
+instance (HasTrie (f x), HasTrie (g x)) => HasTrie ((f :*: g) x) where
+ newtype ((f :*: g) x :->: b) = PairTrie1 ((f x, g x) :->: b)
+ trie f = PairTrie1 (trie (f . liftProduct))
+ untrie (PairTrie1 t) = (untrie t) . dropProduct 
+ enumerate (PairTrie1 t) = enum' liftProduct t
+
+-- | wraps @a@ 
+instance (HasTrie a) => HasTrie (K1 i a x) where
+ data (K1 i a x :->: b) = K1Trie (a :->: b) 
+ trie f = K1Trie (trie (f . K1)) 
+ untrie (K1Trie t) = \(K1 a) -> (untrie t) a 
+ enumerate (K1Trie t) = enum' K1 t 
+
+-- | wraps @f x@ 
+instance (HasTrie (f x)) => HasTrie (M1 i t f x) where
+ data (M1 i t f x :->: b) = M1Trie (f x :->: b) 
+ trie f = M1Trie (trie (f . M1)) 
+ untrie (M1Trie t) = \(M1 a) -> (untrie t) a  
+ enumerate (M1Trie t) = enum' M1 t 
+
+-- | "unlifted" generic representation. (i.e. is a unary type constructor). 
+type Reg a = Rep a () 
+
+trieGeneric
+ :: (Generic a, HasTrie (Reg a))
+ => ((Reg a :->: b) -> (a :->: b))
+ -> (a -> b)
+ -> (a :->: b)
+trieGeneric theConstructor f = theConstructor (trie (f . to))
+{-# INLINEABLE trieGeneric #-}
+
+untrieGeneric
+ :: (Generic a, HasTrie (Reg a))
+ => ((a :->: b) -> (Reg a :->: b))
+ -> (a :->: b)
+ -> (a -> b)
+untrieGeneric theDestructor t = \a -> (untrie (theDestructor t)) (from a)
+{-# INLINEABLE untrieGeneric #-}
+
+enumerateGeneric 
+ :: (Generic a, HasTrie (Reg a))
+ => ((a :->: b) -> (Reg a :->: b))
+ -> (a :->: b)
+ -> [(a, b)]
+enumerateGeneric theDestructor t = enum' to (theDestructor t) 
+{-# INLINEABLE enumerateGeneric #-}
+
+dropProduct :: (f :*: g) a -> (f a, g a) 
+dropProduct (a :*: b) = (a, b)
+{-# INLINEABLE dropProduct #-}
+
+liftProduct :: (f a, g a) -> (f :*: g) a 
+liftProduct (a, b) = (a :*: b)
+{-# INLINEABLE liftProduct #-}
+
+dropSum :: (f :+: g) a -> Either (f a) (g a) 
+dropSum s = case s of 
+ L1 x -> Left x 
+ R1 x -> Right x 
+{-# INLINEABLE dropSum #-}
+
+liftSum :: Either (f a) (g a) -> (f :+: g) a 
+liftSum = either L1 R1
+{-# INLINEABLE liftSum #-}
+
+{- example: 
+
+{-# LANGUAGE DeriveGeneric, TypeOperators #-}
+
+data Color 
+ = RGB Int Int Int
+ | Color String 
+ deriving (Generic) 
+
+instance HasTrie Color where
+ newtype (Color :->: b) = ColorTrie { unColorTrie :: Reg Color :->: b } 
+ trie = trieGeneric ColorTrie 
+ untrie = untrieGeneric unColorTrie
+ enumerate = enumerateGeneric unColorTrie
+
 -}
