diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.markdown
@@ -0,0 +1,36 @@
+## 5.0.2
+* Support GHC-8.2.1
+* Fix Template Haskell derivation with non-default type renamer.
+* Add `Recursive` and `Corecursive Natural` instances, with `Base Natural = Maybe`.
+
+## 5.0.1
+* Add `Data.Functor.Foldable.TH` module, which provides derivation of base functors via Template Haskell.
+
+## 5
+* Renamed `Foldable` to `Recursive` and `Unfoldable` to `Corecursive`. With `Foldable` in `Prelude` in GHC 7.10+, having a needlessly conflicting name seemed silly.
+* Add support for GHC-8.0.1
+* Use `Eq1`, `Ord1`, `Show1`, `Read1` to derive `Fix`, `Nu` and `Mu` `Eq`, `Ord` `Show` and `Read` instances
+* Remove `Prim` data family. `ListF` as a new name for `Prim [a]`, with plenty of instances, e.g. `Traversable`.
+* Export `unfix`
+* Add chronomorphisms: `chrono` and `gchrono`.
+* Add `distGApoT`
+
+## 4.1.2
+* Support for `free` 4.12.1
+
+## 4.1.1
+* Support for GHC 7.10
+* Fixed `para`.
+
+## 4.1
+* Support for GHC 7.7+'s generalized `Typeable`.
+* Faster `gapo` and `para` by exploiting sharing.
+
+## 4.0
+
+* Compatibility with `comonad` and `free` version 4.0
+
+## 3.0
+
+* Compatibility with `transformers` 0.3
+* Resolved deprecation warnings caused by changes to `Data.Typeable`
diff --git a/Data/Functor/Base.hs b/Data/Functor/Base.hs
new file mode 100644
--- /dev/null
+++ b/Data/Functor/Base.hs
@@ -0,0 +1,87 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+
+-- | Base Functors for standard types not already expressed as a fixed point.
+module Data.Functor.Base
+  ( NonEmptyF(..)
+  ) where
+
+import           Data.Data            (Typeable)
+import           GHC.Generics         (Generic, Generic1)
+
+import           Control.Applicative
+import           Data.Monoid
+
+import           Data.Functor.Classes (Eq1 (..), Eq2 (..), Ord1 (..), Ord2 (..),
+                                       Read1 (..), Read2 (..), Show1 (..),
+                                       Show2 (..))
+
+import qualified Data.Foldable        as F
+import qualified Data.Traversable     as T
+
+import qualified Data.Bifoldable      as Bi
+import qualified Data.Bifunctor       as Bi
+import qualified Data.Bitraversable   as Bi
+
+import           Prelude              hiding (head, tail)
+
+-- | Base Functor for 'Data.List.NonEmpty'
+data NonEmptyF a b = NonEmptyF { head :: a, tail :: Maybe b }
+  deriving (Eq,Ord,Show,Read,Typeable
+          , Generic
+          , Generic1
+          )
+
+instance Eq2 NonEmptyF where
+  liftEq2 f g (NonEmptyF a mb) (NonEmptyF a' mb') = f a a' && liftEq g mb mb'
+
+instance Eq a => Eq1 (NonEmptyF a) where
+  liftEq = liftEq2 (==)
+
+instance Ord2 NonEmptyF where
+  liftCompare2 f g (NonEmptyF a mb) (NonEmptyF a' mb') = f a a' `mappend` liftCompare g mb mb'
+
+instance Ord a => Ord1 (NonEmptyF a) where
+  liftCompare = liftCompare2 compare
+
+instance Show a => Show1 (NonEmptyF a) where
+  liftShowsPrec = liftShowsPrec2 showsPrec showList
+
+instance Show2 NonEmptyF where
+  liftShowsPrec2 sa _ sb slb d (NonEmptyF a b) = showParen (d > 10)
+    $ showString "NonEmptyF "
+    . sa 11 a
+    . showString " "
+    . liftShowsPrec sb slb 11 b
+
+instance Read2 NonEmptyF where
+  liftReadsPrec2 ra _ rb rlb d = readParen (d > 10) $ \s -> cons s
+    where
+      cons s0 = do
+        ("NonEmptyF", s1) <- lex s0
+        (a,      s2) <- ra 11 s1
+        (mb,     s3) <- liftReadsPrec rb rlb 11 s2
+        return (NonEmptyF a mb, s3)
+
+instance Read a => Read1 (NonEmptyF a) where
+  liftReadsPrec = liftReadsPrec2 readsPrec readList
+
+-- These instances cannot be auto-derived on with GHC <= 7.6
+instance Functor (NonEmptyF a) where
+  fmap f = NonEmptyF <$> head <*> (fmap f . tail)
+
+instance F.Foldable (NonEmptyF a) where
+  foldMap f = F.foldMap f . tail
+
+instance T.Traversable (NonEmptyF a) where
+  traverse f = fmap <$> (NonEmptyF . head) <*> (T.traverse f . tail)
+
+instance Bi.Bifunctor NonEmptyF where
+  bimap f g = NonEmptyF <$> (f . head) <*> (fmap g . tail)
+
+instance Bi.Bifoldable NonEmptyF where
+  bifoldMap f g = merge <$> (f . head) <*> (fmap g . tail)
+    where merge x = maybe x (mappend x)
+
+instance Bi.Bitraversable NonEmptyF where
+  bitraverse f g = liftA2 NonEmptyF <$> (f . head) <*> (T.traverse g . tail)
diff --git a/Data/Functor/Foldable.hs b/Data/Functor/Foldable.hs
new file mode 100644
--- /dev/null
+++ b/Data/Functor/Foldable.hs
@@ -0,0 +1,388 @@
+{-# LANGUAGE FlexibleContexts        #-}
+{-# LANGUAGE FlexibleInstances       #-}
+{-# LANGUAGE GADTs                   #-}
+{-# LANGUAGE Rank2Types              #-}
+{-# LANGUAGE StandaloneDeriving      #-}
+{-# LANGUAGE TypeFamilies            #-}
+{-# LANGUAGE UndecidableInstances    #-}
+
+{-# LANGUAGE ConstrainedClassMethods #-}
+{-# LANGUAGE DeriveDataTypeable      #-}
+{-# LANGUAGE DeriveGeneric           #-}
+
+
+
+-----------------------------------------------------------------------------
+-- |
+-- Copyright   :  (C) 2008-2015 Edward Kmett
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+----------------------------------------------------------------------------
+module Data.Functor.Foldable
+  (
+  -- * Base functors for fixed points
+    Base
+  , ListF(..)
+  -- * Fixed points
+  , Fix(..), unfix
+  , Mu(..)
+  , Nu(..)
+  -- * Folding
+  , Recursive(..)
+  -- ** Combinators
+  , zygo
+  , mutu
+  -- * Unfolding
+  , Corecursive(..)
+  -- * Refolding
+  , hylo
+  -- ** Changing representation
+  , refix
+  -- * Mendler-style
+  , mcata
+  , mhisto
+  -- * Elgot (co)algebras
+  , elgot
+  , coelgot
+  ) where
+
+import           Control.Applicative
+import           Control.Arrow
+import           Control.Monad        (join)
+import           Data.Data
+import           Data.Function        (on)
+import           Data.Functor.Classes
+import           Data.List.NonEmpty   (NonEmpty ((:|)), nonEmpty, toList)
+import           Data.Monoid          (Monoid (..))
+import           GHC.Generics         (Generic, Generic1)
+import           Numeric.Natural
+import           Prelude
+import           Text.Read
+
+import qualified Data.Foldable        as F
+import qualified Data.Traversable     as T
+
+import qualified Data.Bifoldable      as Bi
+import qualified Data.Bifunctor       as Bi
+import qualified Data.Bitraversable   as Bi
+
+import           Data.Functor.Base
+import qualified Data.Functor.Base    as NEF (NonEmptyF (..))
+
+type family Base t :: * -> *
+
+class Functor (Base t) => Recursive t where
+  project :: t -> Base t t
+
+  cata :: (Base t a -> a) -- ^ a (Base t)-algebra
+       -> t               -- ^ fixed point
+       -> a               -- ^ result
+  cata f = c where c = f . fmap c . project
+
+  para :: (Base t (t, a) -> a) -> t -> a
+  para t = p where p x = t . fmap ((,) <*> p) $ project x
+
+  -- | Fokkinga's prepromorphism
+  prepro
+    :: Corecursive t
+    => (forall b. Base t b -> Base t b)
+    -> (Base t a -> a)
+    -> t
+    -> a
+  prepro e f = c where c = f . fmap (c . cata (embed . e)) . project
+
+class Functor (Base t) => Corecursive t where
+  embed :: Base t t -> t
+  ana
+    :: (a -> Base t a) -- ^ a (Base t)-coalgebra
+    -> a               -- ^ seed
+    -> t               -- ^ resulting fixed point
+  ana g = a where a = embed . fmap a . g
+
+  apo :: (a -> Base t (Either t a)) -> a -> t
+  apo g = a where a = embed . fmap (either id a) . g
+
+  -- | Fokkinga's postpromorphism
+  postpro
+    :: Recursive t
+    => (forall b. Base t b -> Base t b) -- natural transformation
+    -> (a -> Base t a)                  -- a (Base t)-coalgebra
+    -> a                                -- seed
+    -> t
+  postpro e g = a where a = embed . fmap (ana (e . project) . a) . g
+
+  -- | A generalized postpromorphism
+  gpostpro
+    :: (Recursive t, Monad m)
+    => (forall b. m (Base t b) -> Base t (m b)) -- distributive law
+    -> (forall c. Base t c -> Base t c)         -- natural transformation
+    -> (a -> Base t (m a))                      -- a (Base t)-m-coalgebra
+    -> a                                        -- seed
+    -> t
+  gpostpro k e g = a . return where a = embed . fmap (ana (e . project) . a . join) . k . fmap g
+
+hylo :: Functor f => (f b -> b) -> (a -> f a) -> a -> b
+hylo f g = h where h = f . fmap h . g
+
+-- | Base functor of @[]@.
+data ListF a b = Nil | Cons a b
+  deriving (Eq,Ord,Show,Read,Typeable
+          , Generic
+          , Generic1
+          )
+
+instance Eq2 ListF where
+  liftEq2 _ _ Nil        Nil          = True
+  liftEq2 f g (Cons a b) (Cons a' b') = f a a' && g b b'
+  liftEq2 _ _ _          _            = False
+
+instance Eq a => Eq1 (ListF a) where
+  liftEq = liftEq2 (==)
+
+instance Ord2 ListF where
+  liftCompare2 _ _ Nil        Nil          = EQ
+  liftCompare2 _ _ Nil        _            = LT
+  liftCompare2 _ _ _          Nil          = GT
+  liftCompare2 f g (Cons a b) (Cons a' b') = f a a' `mappend` g b b'
+
+instance Ord a => Ord1 (ListF a) where
+  liftCompare = liftCompare2 compare
+
+instance Show a => Show1 (ListF a) where
+  liftShowsPrec = liftShowsPrec2 showsPrec showList
+
+instance Show2 ListF where
+  liftShowsPrec2 _  _ _  _ _ Nil        = showString "Nil"
+  liftShowsPrec2 sa _ sb _ d (Cons a b) = showParen (d > 10)
+    $ showString "Cons "
+    . sa 11 a
+    . showString " "
+    . sb 11 b
+
+instance Read2 ListF where
+  liftReadsPrec2 ra _ rb _ d = readParen (d > 10) $ \s -> nil s ++ cons s
+    where
+      nil s0 = do
+        ("Nil", s1) <- lex s0
+        return (Nil, s1)
+      cons s0 = do
+        ("Cons", s1) <- lex s0
+        (a,      s2) <- ra 11 s1
+        (b,      s3) <- rb 11 s2
+        return (Cons a b, s3)
+
+instance Read a => Read1 (ListF a) where
+  liftReadsPrec = liftReadsPrec2 readsPrec readList
+
+-- These instances cannot be auto-derived on with GHC <= 7.6
+instance Functor (ListF a) where
+  fmap _ Nil        = Nil
+  fmap f (Cons a b) = Cons a (f b)
+
+instance F.Foldable (ListF a) where
+  foldMap _ Nil        = Data.Monoid.mempty
+  foldMap f (Cons _ b) = f b
+
+instance T.Traversable (ListF a) where
+  traverse _ Nil        = pure Nil
+  traverse f (Cons a b) = Cons a <$> f b
+
+instance Bi.Bifunctor ListF where
+  bimap _ _ Nil        = Nil
+  bimap f g (Cons a b) = Cons (f a) (g b)
+
+instance Bi.Bifoldable ListF where
+  bifoldMap _ _ Nil        = mempty
+  bifoldMap f g (Cons a b) = mappend (f a) (g b)
+
+instance Bi.Bitraversable ListF where
+  bitraverse _ _ Nil        = pure Nil
+  bitraverse f g (Cons a b) = Cons <$> f a <*> g b
+
+type instance Base [a] = ListF a
+instance Recursive [a] where
+  project (x:xs) = Cons x xs
+  project []     = Nil
+
+  para f (x:xs) = f (Cons x (xs, para f xs))
+  para f []     = f Nil
+
+instance Corecursive [a] where
+  embed (Cons x xs) = x:xs
+  embed Nil         = []
+
+  apo f a = case f a of
+    Cons x (Left xs) -> x : xs
+    Cons x (Right b) -> x : apo f b
+    Nil              -> []
+
+type instance Base (NonEmpty a) = NonEmptyF a
+instance Recursive (NonEmpty a) where
+  project (x:|xs) = NonEmptyF x $ nonEmpty xs
+instance Corecursive (NonEmpty a) where
+  embed = (:|) <$> NEF.head <*> (maybe [] toList <$> NEF.tail)
+
+type instance Base Natural = Maybe
+instance Recursive Natural where
+  project 0 = Nothing
+  project n = Just (n - 1)
+instance Corecursive Natural where
+  embed = maybe 0 (+1)
+
+-- If you are looking for instances for the free alternative and free
+-- applicative, I'm sorry to disapoint you but you won't find them in this
+-- package.  They can be considered recurive, but using non-uniform recursion;
+-- this package only implements uniformly recursive folds / unfolds.
+
+-- | Example boring stub for non-recursive data types
+type instance Base (Maybe a) = Const (Maybe a)
+instance Recursive (Maybe a) where project = Const
+instance Corecursive (Maybe a) where embed = getConst
+
+-- | Example boring stub for non-recursive data types
+type instance Base (Either a b) = Const (Either a b)
+instance Recursive (Either a b) where project = Const
+instance Corecursive (Either a b) where embed = getConst
+
+-------------------------------------------------------------------------------
+-- Fix
+-------------------------------------------------------------------------------
+
+newtype Fix f = Fix (f (Fix f))
+
+unfix :: Fix f -> f (Fix f)
+unfix (Fix f) = f
+
+instance Eq1 f => Eq (Fix f) where
+  Fix a == Fix b = eq1 a b
+
+instance Ord1 f => Ord (Fix f) where
+  compare (Fix a) (Fix b) = compare1 a b
+
+instance Show1 f => Show (Fix f) where
+  showsPrec d (Fix a) =
+    showParen (d >= 11)
+      $ showString "Fix "
+      . showsPrec1 11 a
+
+instance Read1 f => Read (Fix f) where
+  readPrec = parens $ prec 10 $ do
+    Ident "Fix" <- lexP
+    Fix <$> step (readS_to_Prec readsPrec1)
+
+deriving instance Typeable Fix
+deriving instance (Typeable f, Data (f (Fix f))) => Data (Fix f)
+
+type instance Base (Fix f) = f
+instance Functor f => Recursive (Fix f) where
+  project (Fix a) = a
+instance Functor f => Corecursive (Fix f) where
+  embed = Fix
+
+refix :: (Recursive s, Corecursive t, Base s ~ Base t) => s -> t
+refix = cata embed
+
+toFix :: Recursive t => t -> Fix (Base t)
+toFix = refix
+
+fromFix :: Corecursive t => Fix (Base t) -> t
+fromFix = refix
+
+-------------------------------------------------------------------------------
+-- Lambek
+-------------------------------------------------------------------------------
+
+-- | Lambek's lemma provides a default definition for 'project' in terms of 'cata' and 'embed'
+lambek :: (Recursive t, Corecursive t) => (t -> Base t t)
+lambek = cata (fmap embed)
+
+-- | The dual of Lambek's lemma, provides a default definition for 'embed' in terms of 'ana' and 'project'
+colambek :: (Recursive t, Corecursive t) => (Base t t -> t)
+colambek = ana (fmap project)
+
+newtype Mu f = Mu (forall a. (f a -> a) -> a)
+type instance Base (Mu f) = f
+instance Functor f => Recursive (Mu f) where
+  project = lambek
+  cata f (Mu g) = g f
+instance Functor f => Corecursive (Mu f) where
+  embed m = Mu (\f -> f (fmap (cata f) m))
+
+instance (Functor f, Eq1 f) => Eq (Mu f) where
+  (==) = (==) `on` toFix
+
+instance (Functor f, Ord1 f) => Ord (Mu f) where
+  compare = compare `on` toFix
+
+instance (Functor f, Show1 f) => Show (Mu f) where
+  showsPrec d f = showParen (d > 10) $
+    showString "fromFix " . showsPrec 11 (toFix f)
+
+instance (Functor f, Read1 f) => Read (Mu f) where
+  readPrec = parens $ prec 10 $ do
+    Ident "fromFix" <- lexP
+    fromFix <$> step readPrec
+
+data Nu f where Nu :: (a -> f a) -> a -> Nu f
+type instance Base (Nu f) = f
+instance Functor f => Corecursive (Nu f) where
+  embed = colambek
+  ana = Nu
+instance Functor f => Recursive (Nu f) where
+  project (Nu f a) = Nu f <$> f a
+
+instance (Functor f, Eq1 f) => Eq (Nu f) where
+  (==) = (==) `on` toFix
+
+instance (Functor f, Ord1 f) => Ord (Nu f) where
+  compare = compare `on` toFix
+
+instance (Functor f, Show1 f) => Show (Nu f) where
+  showsPrec d f = showParen (d > 10) $
+    showString "fromFix " . showsPrec 11 (toFix f)
+
+instance (Functor f, Read1 f) => Read (Nu f) where
+  readPrec = parens $ prec 10 $ do
+    Ident "fromFix" <- lexP
+    fromFix <$> step readPrec
+
+zygo :: Recursive t => (Base t b -> b) -> (Base t (b, a) -> a) -> t -> a
+zygo f g = snd . cata (\x -> (f (fmap fst x), g x))
+
+mutu :: (Recursive t) => (Base t (a, a) -> a) -> (Base t (a, a) -> a) -> t -> a
+mutu f g = g . fmap (\x -> (mutu g f x, mutu f g x)) . project
+
+-- | Mendler-style iteration
+mcata :: (forall y. (y -> c) -> f y -> c) -> Fix f -> c
+mcata psi = psi (mcata psi) . unfix
+
+-- | Mendler-style course-of-value iteration
+mhisto :: (forall y. (y -> c) -> (y -> f y) -> f y -> c) -> Fix f -> c
+mhisto psi = psi (mhisto psi) unfix . unfix
+
+-- | Elgot algebras
+elgot :: Functor f => (f a -> a) -> (b -> Either a (f b)) -> b -> a
+elgot phi psi = h where h = (id ||| phi . fmap h) . psi
+
+-- | Elgot coalgebras: <http://comonad.com/reader/2008/elgot-coalgebras/>
+coelgot :: Functor f => ((a, f b) -> b) -> (a -> f a) -> a -> b
+coelgot phi psi = h where h = phi . (id &&& fmap h . psi)
+
+-------------------------------------------------------------------------------
+-- Not exposed anywhere
+-------------------------------------------------------------------------------
+
+-- | Read a list (using square brackets and commas), given a function
+-- for reading elements.
+_readListWith :: ReadS a -> ReadS [a]
+_readListWith rp =
+    readParen False (\r -> [pr | ("[",s) <- lex r, pr <- readl s])
+  where
+    readl s = [([],t) | ("]",t) <- lex s] ++
+        [(x:xs,u) | (x,t) <- rp s, (xs,u) <- readl' t]
+    readl' s = [([],t) | ("]",t) <- lex s] ++
+        [(x:xs,v) | (",",t) <- lex s, (x,u) <- rp t, (xs,v) <- readl' u]
diff --git a/Data/Functor/Foldable/TH.hs b/Data/Functor/Foldable/TH.hs
new file mode 100644
--- /dev/null
+++ b/Data/Functor/Foldable/TH.hs
@@ -0,0 +1,368 @@
+{-# LANGUAGE CPP        #-}
+{-# LANGUAGE Rank2Types #-}
+module Data.Functor.Foldable.TH
+  ( makeBaseFunctor
+  , makeBaseFunctorWith
+  , BaseRules
+  , baseRules
+  , baseRulesType
+  , baseRulesCon
+  , baseRulesField
+  ) where
+
+import           Control.Applicative          as A
+import           Control.Monad
+import           Data.Char                    (GeneralCategory (..),
+                                               generalCategory)
+import           Data.Functor.Identity
+import           Data.Traversable             as T
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Datatype as TH.Abs
+import           Language.Haskell.TH.Syntax   (mkNameG_tc, mkNameG_v)
+
+-- | Build base functor with a sensible default configuration.
+--
+-- /e.g./
+--
+-- @
+-- data Expr a
+--     = Lit a
+--     | Add (Expr a) (Expr a)
+--     | Expr a :* [Expr a]
+--   deriving (Show)
+--
+-- 'makeBaseFunctor' ''Expr
+-- @
+--
+-- will create
+--
+-- @
+-- data ExprF a x
+--     = LitF a
+--     | AddF x x
+--     | x :*$ [x]
+--   deriving ('Functor', 'Foldable', 'Traversable')
+--
+-- type instance 'Base' (Expr a) = ExprF a
+--
+-- instance 'Recursive' (Expr a) where
+--     'project' (Lit x)   = LitF x
+--     'project' (Add x y) = AddF x y
+--     'project' (x :* y)  = x :*$ y
+--
+-- instance 'Corecursive' (Expr a) where
+--     'embed' (LitF x)   = Lit x
+--     'embed' (AddF x y) = Add x y
+--     'embed' (x :*$ y)  = x :*$ y
+-- @
+--
+-- @
+-- 'makeBaseFunctor' = 'makeBaseFunctorWith' 'baseRules'
+-- @
+--
+-- /Notes:/
+--
+-- 'makeBaseFunctor' works properly only with ADTs.
+-- Existentials and GADTs aren't supported,
+-- as we don't try to do better than
+-- <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#deriving-functor-instances GHC's DeriveFunctor>.
+--
+makeBaseFunctor :: Name -> DecsQ
+makeBaseFunctor = makeBaseFunctorWith baseRules
+
+-- | Build base functor with a custom configuration.
+makeBaseFunctorWith :: BaseRules -> Name -> DecsQ
+makeBaseFunctorWith rules name = reifyDatatype name >>= makePrimForDI rules
+
+-- | Rules of renaming data names
+data BaseRules = BaseRules
+    { _baseRulesType  :: Name -> Name
+    , _baseRulesCon   :: Name -> Name
+    , _baseRulesField :: Name -> Name
+    }
+
+-- | Default 'BaseRules': append @F@ or @$@ to data type, constructors and field names.
+baseRules :: BaseRules
+baseRules = BaseRules
+    { _baseRulesType  = toFName
+    , _baseRulesCon   = toFName
+    , _baseRulesField = toFName
+    }
+
+-- | How to name the base functor type.
+--
+-- Default is to append @F@ or @$@.
+baseRulesType :: Functor f => ((Name -> Name) -> f (Name -> Name)) -> BaseRules -> f BaseRules
+baseRulesType f rules = (\x -> rules { _baseRulesType = x }) <$> f (_baseRulesType rules)
+
+-- | How to rename the base functor type constructors.
+--
+-- Default is to append @F@ or @$@.
+baseRulesCon :: Functor f => ((Name -> Name) -> f (Name -> Name)) -> BaseRules -> f BaseRules
+baseRulesCon f rules = (\x -> rules { _baseRulesCon = x }) <$> f (_baseRulesCon rules)
+
+-- | How to rename the base functor type field names (in records).
+--
+-- Default is to append @F@ or @$@.
+baseRulesField :: Functor f => ((Name -> Name) -> f (Name -> Name)) -> BaseRules -> f BaseRules
+baseRulesField f rules = (\x -> rules { _baseRulesField = x }) <$> f (_baseRulesField rules)
+
+toFName :: Name -> Name
+toFName = mkName . f . nameBase
+  where
+    f name | isInfixName name = name ++ "$"
+           | otherwise        = name ++ "F"
+
+    isInfixName :: String -> Bool
+    isInfixName = all isSymbolChar
+
+makePrimForDI :: BaseRules -> DatatypeInfo -> DecsQ
+makePrimForDI rules
+  DatatypeInfo { datatypeName    = tyName
+                , datatypeVars    = vars
+                , datatypeCons    = cons
+                , datatypeVariant = variant } = do
+    when isDataFamInstance $
+      fail "makeBaseFunctor: Data families are currently not supported."
+    makePrimForDI' rules (variant == Newtype) tyName
+                   (map toTyVarBndr vars) cons
+  where
+    isDataFamInstance = case variant of
+                          DataInstance    -> True
+                          NewtypeInstance -> True
+                          Datatype        -> False
+                          Newtype         -> False
+
+    toTyVarBndr :: Type -> TyVarBndr
+    toTyVarBndr (VarT n)          = PlainTV n
+    toTyVarBndr (SigT (VarT n) k) = KindedTV n k
+    toTyVarBndr _                 = error "toTyVarBndr"
+
+makePrimForDI' :: BaseRules -> Bool -> Name -> [TyVarBndr]
+               -> [ConstructorInfo] -> DecsQ
+makePrimForDI' rules isNewtype tyName vars cons = do
+    -- variable parameters
+    let vars' = map VarT (typeVars vars)
+    -- Name of base functor
+    let tyNameF = _baseRulesType rules tyName
+    -- Recursive type
+    let s = conAppsT tyName vars'
+    -- Additional argument
+    rName <- newName "r"
+    let r = VarT rName
+    -- Vars
+    let varsF = vars ++ [PlainTV rName]
+
+    -- #33
+    cons' <- traverse (conTypeTraversal resolveTypeSynonyms) cons
+    let consF
+          = toCon
+          . conNameMap (_baseRulesCon rules)
+          . conFieldNameMap (_baseRulesField rules)
+          . conTypeMap (substType s r)
+          <$> cons'
+
+    -- Data definition
+    let dataDec = case consF of
+            [conF] | isNewtype ->
+                NewtypeD [] tyNameF varsF Nothing conF deriveds
+            _ ->
+                DataD [] tyNameF varsF Nothing consF deriveds
+          where
+            deriveds =
+              [DerivClause Nothing
+                [ ConT functorTypeName
+                , ConT foldableTypeName
+                , ConT traversableTypeName ]]
+
+    -- type instance Base
+    let baseDec = TySynInstD baseTypeName (TySynEqn [s] $ conAppsT tyNameF vars')
+
+    -- instance Recursive
+    projDec <- FunD projectValName <$> mkMorphism id (_baseRulesCon rules) cons'
+    let recursiveDec = InstanceD Nothing [] (ConT recursiveTypeName `AppT` s) [projDec]
+
+    -- instance Corecursive
+    embedDec <- FunD embedValName <$> mkMorphism (_baseRulesCon rules) id cons'
+    let corecursiveDec = InstanceD Nothing [] (ConT corecursiveTypeName `AppT` s) [embedDec]
+
+    -- Combine
+    A.pure [dataDec, baseDec, recursiveDec, corecursiveDec]
+
+-- | makes clauses to rename constructors
+mkMorphism
+    :: (Name -> Name)
+    -> (Name -> Name)
+    -> [ConstructorInfo]
+    -> Q [Clause]
+mkMorphism nFrom nTo args = for args $ \ci -> do
+    let n = constructorName ci
+    fs <- replicateM (length (constructorFields ci)) (newName "x")
+    pure $ Clause [ConP (nFrom n) (map VarP fs)]                      -- patterns
+                  (NormalB $ foldl AppE (ConE $ nTo n) (map VarE fs)) -- body
+                  [] -- where dec
+
+-------------------------------------------------------------------------------
+-- Traversals
+-------------------------------------------------------------------------------
+
+conNameTraversal :: Traversal' ConstructorInfo Name
+conNameTraversal = lens constructorName (\s v -> s { constructorName = v })
+
+conFieldNameTraversal :: Traversal' ConstructorInfo Name
+conFieldNameTraversal = lens constructorVariant (\s v -> s { constructorVariant = v })
+                      . conVariantTraversal
+  where
+    conVariantTraversal :: Traversal' ConstructorVariant Name
+    conVariantTraversal _ NormalConstructor      = pure NormalConstructor
+    conVariantTraversal _ InfixConstructor       = pure InfixConstructor
+    conVariantTraversal f (RecordConstructor fs) = RecordConstructor <$> traverse f fs
+
+conTypeTraversal :: Traversal' ConstructorInfo Type
+conTypeTraversal = lens constructorFields (\s v -> s { constructorFields = v })
+                 . traverse
+
+conNameMap :: (Name -> Name) -> ConstructorInfo -> ConstructorInfo
+conNameMap = over conNameTraversal
+
+conFieldNameMap :: (Name -> Name) -> ConstructorInfo -> ConstructorInfo
+conFieldNameMap = over conFieldNameTraversal
+
+conTypeMap :: (Type -> Type) -> ConstructorInfo -> ConstructorInfo
+conTypeMap = over conTypeTraversal
+
+-------------------------------------------------------------------------------
+-- Lenses
+-------------------------------------------------------------------------------
+
+type Lens'      s a = forall f. Functor     f => (a -> f a) -> s -> f s
+type Traversal' s a = forall f. Applicative f => (a -> f a) -> s -> f s
+
+lens :: (s -> a) -> (s -> a -> s) -> Lens' s a
+lens sa sas afa s = sas s <$> afa (sa s)
+{-# INLINE lens #-}
+
+over :: Traversal' s a -> (a -> a) -> s -> s
+over l f = runIdentity . l (Identity . f)
+{-# INLINE over #-}
+
+-------------------------------------------------------------------------------
+-- Type mangling
+-------------------------------------------------------------------------------
+
+-- | Extract type variables
+typeVars :: [TyVarBndr] -> [Name]
+typeVars = map tvName
+
+-- | Apply arguments to a type constructor.
+conAppsT :: Name -> [Type] -> Type
+conAppsT conName = foldl AppT (ConT conName)
+
+-- | Provides substitution for types
+substType
+    :: Type
+    -> Type
+    -> Type
+    -> Type
+substType a b = go
+  where
+    go x                  | x == a         = b
+    go (VarT n)           = VarT n
+    go (AppT l r)         = AppT (go l) (go r)
+    go (ForallT xs ctx t) = ForallT xs ctx (go t)
+    -- This may fail with kind error
+    go (SigT t k)         = SigT (go t) k
+    go (InfixT l n r)     = InfixT (go l) n (go r)
+    go (UInfixT l n r)    = UInfixT (go l) n (go r)
+    go (ParensT t)        = ParensT (go t)
+    -- Rest are unchanged
+    go x                  = x
+
+toCon :: ConstructorInfo -> Con
+toCon ConstructorInfo { constructorName       = name
+                       , constructorVars       = vars
+                       , constructorContext    = ctxt
+                       , constructorFields     = ftys
+                       , constructorStrictness = fstricts
+                       , constructorVariant    = variant }
+  | not (null vars && null ctxt)
+  = error "makeBaseFunctor: GADTs are not currently supported."
+  | otherwise
+  = let bangs = map toBang fstricts
+     in case variant of
+          NormalConstructor        -> NormalC name $ zip bangs ftys
+          RecordConstructor fnames -> RecC name $ zip3 fnames bangs ftys
+          InfixConstructor         -> let [bang1, bang2] = bangs
+                                          [fty1,  fty2]  = ftys
+                                       in InfixC (bang1, fty1) name (bang2, fty2)
+  where
+    toBang (FieldStrictness upkd strct) = Bang (toSourceUnpackedness upkd)
+                                               (toSourceStrictness strct)
+      where
+        toSourceUnpackedness :: Unpackedness -> SourceUnpackedness
+        toSourceUnpackedness UnspecifiedUnpackedness = NoSourceUnpackedness
+        toSourceUnpackedness NoUnpack                = SourceNoUnpack
+        toSourceUnpackedness Unpack                  = SourceUnpack
+
+        toSourceStrictness :: Strictness -> SourceStrictness
+        toSourceStrictness UnspecifiedStrictness = NoSourceStrictness
+        toSourceStrictness Lazy                  = SourceLazy
+        toSourceStrictness TH.Abs.Strict         = SourceStrict
+
+-------------------------------------------------------------------------------
+-- Compat from base-4.9
+-------------------------------------------------------------------------------
+
+isSymbolChar :: Char -> Bool
+isSymbolChar c = not (isPuncChar c) && case generalCategory c of
+    MathSymbol           -> True
+    CurrencySymbol       -> True
+    ModifierSymbol       -> True
+    OtherSymbol          -> True
+    DashPunctuation      -> True
+    OtherPunctuation     -> c `notElem` "'\""
+    ConnectorPunctuation -> c /= '_'
+    _                    -> False
+
+isPuncChar :: Char -> Bool
+isPuncChar c = c `elem` ",;()[]{}`"
+
+-------------------------------------------------------------------------------
+-- Manually quoted names
+-------------------------------------------------------------------------------
+-- By manually generating these names we avoid needing to use the
+-- TemplateHaskell language extension when compiling this library.
+-- This allows the library to be used in stage1 cross-compilers.
+
+rsPackageKey :: String
+rsPackageKey = CURRENT_PACKAGE_KEY
+
+mkRsName_tc :: String -> String -> Name
+mkRsName_tc = mkNameG_tc rsPackageKey
+
+mkRsName_v :: String -> String -> Name
+mkRsName_v = mkNameG_v rsPackageKey
+
+baseTypeName :: Name
+baseTypeName = mkRsName_tc "Data.Functor.Foldable" "Base"
+
+recursiveTypeName :: Name
+recursiveTypeName = mkRsName_tc "Data.Functor.Foldable" "Recursive"
+
+corecursiveTypeName :: Name
+corecursiveTypeName = mkRsName_tc "Data.Functor.Foldable" "Corecursive"
+
+projectValName :: Name
+projectValName = mkRsName_v "Data.Functor.Foldable" "project"
+
+embedValName :: Name
+embedValName = mkRsName_v "Data.Functor.Foldable" "embed"
+
+functorTypeName :: Name
+functorTypeName = mkNameG_tc "base" "GHC.Base" "Functor"
+
+foldableTypeName :: Name
+foldableTypeName = mkNameG_tc "base" "Data.Foldable" "Foldable"
+
+traversableTypeName :: Name
+traversableTypeName = mkNameG_tc "base" "Data.Traversable" "Traversable"
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2011-2015 Edward Kmett, 2018 Vanessa McHale
+
+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.
+
+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/README.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,9 @@
+micro-recursion-schemes
+==========
+
+[![Hackage](https://img.shields.io/hackage/v/micro-recursion-schemes.svg)](https://hackage.haskell.org/package/micro-recursion-schemes) [![Build Status](https://secure.travis-ci.org/ekmett/micro-recursion-schemes.png?branch=master)](http://travis-ci.org/ekmett/micro-recursion-schemes)
+
+This is a fork of the
+[recursion-schemes](http://hackage.haskell.org/package/recursion-schemes)
+package that aims to have few dependencies and optionally no dependence on
+`cpphs`.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/cabal.project.local b/cabal.project.local
new file mode 100644
--- /dev/null
+++ b/cabal.project.local
@@ -0,0 +1,2 @@
+tests: true
+documentation: true
diff --git a/examples/Expr.hs b/examples/Expr.hs
new file mode 100644
--- /dev/null
+++ b/examples/Expr.hs
@@ -0,0 +1,97 @@
+{-# LANGUAGE DeriveFoldable    #-}
+{-# LANGUAGE DeriveFunctor     #-}
+{-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE KindSignatures    #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeFamilies      #-}
+module Main where
+
+import           Data.Functor.Foldable
+import           Data.Functor.Foldable.TH
+import           Data.Functor.Identity
+import           Data.List                (foldl')
+import           Language.Haskell.TH
+import           Test.HUnit
+
+data Expr a
+    = Lit a
+    | Add (Expr a) (Expr a)
+    | Expr a :* [Expr a]
+  deriving (Show)
+
+makeBaseFunctor ''Expr
+
+data Expr2 a
+    = Lit2 a
+    | Add2 (Expr2 a) (Expr2 a)
+  deriving (Show)
+
+makeBaseFunctorWith (runIdentity $ baseRulesCon (\_-> Identity $ mkName . (++ "'") . nameBase) baseRules
+    >>= baseRulesType (\_ -> Identity $ mkName . (++ "_") . nameBase)
+    ) ''Expr2
+
+expr1 :: Expr Int
+expr1 = Add (Lit 2) (Lit 3 :* [Lit 4])
+
+-- This is to test newtype derivation
+--
+-- Kind of a list
+newtype L a = L { getL :: Maybe (a, L a) }
+  deriving (Show, Eq)
+
+makeBaseFunctor ''L
+
+cons :: a -> L a -> L a
+cons x xs = L (Just (x, xs))
+
+nil :: L a
+nil = L Nothing
+
+-- Test #33
+data Tree a = Node {rootLabel :: a, subForest :: Forest a}
+  deriving (Show)
+type Forest a = [Tree a]
+
+makeBaseFunctor ''Tree
+
+main :: IO ()
+main = do
+    let expr2 = ana divCoalg 55 :: Expr Int
+    14 @=? cata evalAlg expr1
+    55 @=? cata evalAlg expr2
+
+    let lBar = cons 'b' $ cons 'a' $ cons 'r' nil
+    "bar" @=? cata lAlg lBar
+    lBar @=? ana lCoalg "bar"
+
+    let expr3 = Add2 (Lit2 21) $ Add2 (Lit2 11) (Lit2 10)
+    42 @=? cata evalAlg2 expr3
+
+    let expr4 = Node 5 [Node 6 [Node 7 []], Node 8 [Node 9 []]]
+    35 @=? cata treeAlg expr4
+  where
+    -- Type signatures to test name generation
+    evalAlg :: ExprF Int Int -> Int
+    evalAlg (LitF x)   = x
+    evalAlg (AddF x y) = x + y
+    evalAlg (x :*$ y)  = foldl' (*) x y
+
+    evalAlg2 :: Expr2_ Int Int -> Int
+    evalAlg2 (Lit2' x)   = x
+    evalAlg2 (Add2' x y) = x + y
+
+    divCoalg x
+        | x < 5     = LitF x
+        | even x    = 2 :*$ [x']
+        | otherwise = AddF x' (x - x')
+      where
+        x' = x `div` 2
+
+    lAlg (LF Nothing)        = []
+    lAlg (LF (Just (x, xs))) = x : xs
+
+    lCoalg []       = LF { getLF = Nothing } -- to test field renamer
+    lCoalg (x : xs) = LF { getLF = Just (x, xs) }
+
+    treeAlg :: TreeF Int Int -> Int
+    treeAlg (NodeF r f) = r + sum f
diff --git a/micro-recursion-schemes.cabal b/micro-recursion-schemes.cabal
new file mode 100644
--- /dev/null
+++ b/micro-recursion-schemes.cabal
@@ -0,0 +1,59 @@
+cabal-version: 1.18
+name: micro-recursion-schemes
+version: 5.0.2.1
+license: BSD3
+license-file: LICENSE
+copyright: Copyright (C) 2008-2015 Edward A. Kmett, 2018 Vanessa McHale
+maintainer: vmchale@gmail.com
+author: Vanessa McHale, Edward A. Kmett
+tested-with: ghc ==8.2.2 ghc ==8.4.1
+synopsis: Simple recursion schemes
+description:
+    This package provides the core functionality of [recursion-schemes](http://hackage.haskell.org/package/recursion-schemes), but without odious dependencies on unneeded packages.
+category: Control, Recursion
+build-type: Simple
+extra-source-files:
+    cabal.project.local
+    stack.yaml
+extra-doc-files: README.markdown
+                 CHANGELOG.markdown
+
+source-repository head
+    type: git
+    location: git://github.com/vmchale/micro-recursion-schemes.git
+
+flag template-haskell
+    description:
+        Enable Template Haskell functionality
+    manual: True
+
+library
+    exposed-modules:
+        Data.Functor.Base
+        Data.Functor.Foldable
+    default-language: Haskell2010
+    other-extensions: TypeFamilies Rank2Types FlexibleContexts
+                      FlexibleInstances GADTs StandaloneDeriving UndecidableInstances
+    ghc-options: -Wall
+    build-depends:
+        base >=4.10 && <5
+    
+    if flag(template-haskell)
+        exposed-modules:
+            Data.Functor.Foldable.TH
+        build-tools: cpphs -any
+        build-depends:
+            th-abstraction >=0.2.4 && <1,
+            template-haskell >=2.5.0.0 && <2.14
+
+test-suite Expr
+    type: exitcode-stdio-1.0
+    main-is: Expr.hs
+    hs-source-dirs: examples
+    default-language: Haskell2010
+    ghc-options: -Wall -threaded
+    build-depends:
+        base -any,
+        HUnit <1.7,
+        micro-recursion-schemes -any,
+        template-haskell >=2.5.0.0 && <2.14
diff --git a/stack.yaml b/stack.yaml
new file mode 100644
--- /dev/null
+++ b/stack.yaml
@@ -0,0 +1,2 @@
+---
+resolver: lts-11.4
