diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,38 @@
+## 0.3.4
+
+- Use quantified constraints superclasses for `Eq`, `Ord`, `NFData` and
+  `Hashable Fix` instances, when available.
+
+## 0.3.3
+
+- Drop support for GHCs prior 8.6.5
+
+## 0.3.2
+
+- Add `(un)wrapFix/Mu/Nu`
+- Support `transformers-0.6`
+
+## 0.3.1
+
+- Update bounds for GHC-9.0
+
+## 0.3.0
+
+- Rename `cata`, `ana` and `hylo` into `foldFix`, `unfoldFix` and `refold.
+  Old names are now deprecated, and will be eventually removed.
+  Similarly, rename monadic variants.
+- Add `hoistFix` and `hoistFix'` function.
+- Add `Hashable` and `NFData` instance.
+  Latter is available only with `deepseq >=1.4.3.0`,
+  which provides `NFData1` type-class
+- Change `Eq`, `Ord`, `Show` and `Read` instances to use
+  `Eq1`, `Ord1`, `Show1` and `Read1` instances of a base functor.
+- Add least and greatest fixed point types, `Mu` and `Nu`.
+- Drop requirement for `Applicative m` in monadic combinators,
+  `Monad m` is enough.
+- Remove `~>` alias for `refold` (`hylo`).
+- Extend the GHC support window.
+  There is nothing magical in this package.
+- Mark `Data.Fix` as Trustworthy (Safe Haskell)
+- Make `refold` (and `refoldM`) more efficient.
+  This results in different effect ordering for `refoldM`.
diff --git a/data-fix.cabal b/data-fix.cabal
--- a/data-fix.cabal
+++ b/data-fix.cabal
@@ -1,14 +1,14 @@
+cabal-version:   2.2
 Name:            data-fix
-Version:         0.0.7
-Cabal-Version:   >= 1.10
-License:         BSD3
+Version:         0.3.4
+License:         BSD-3-Clause
 License-file:    LICENSE
-Author:          Anton Kholomiov
+Author:          Anton Kholomiov, Edward Kmett, Oleg Grenrus
 Maintainer:      <anton.kholomiov@gmail.com>
 Category:        Data
 Synopsis:        Fixpoint data types
 Build-Type:      Simple
-Description:     
+Description:
   Fixpoint types and recursion schemes. If you define your AST as
   fixpoint type, you get fold and unfold operations for free.
   .
@@ -16,19 +16,39 @@
 
 Stability:       Experimental
 
-Homepage:        https://github.com/anton-k/data-fix
-Bug-Reports:     https://github.com/anton-k/data-fix/issues
+Homepage:        https://github.com/spell-music/data-fix
+Bug-Reports:     https://github.com/spell-music/data-fix/issues
 
+Tested-With:
+  GHC ==8.6.5
+   || ==8.8.4
+   || ==8.10.7
+   || ==9.0.2
+   || ==9.2.8
+   || ==9.4.8
+   || ==9.6.6
+   || ==9.8.2
+   || ==9.10.1
+
+extra-source-files:
+  CHANGELOG.md
+
 Source-repository head
     Type: git
-    Location: https://github.com/anton-k/data-fix
+    Location: https://github.com/spell-music/data-fix
 
-Library
-  Default-Language: Haskell2010
-  Build-depends: base >= 4.7, base < 5
-  Hs-source-dirs: src/
+library
+  hs-source-dirs:   src
+  default-language: Haskell2010
+  ghc-options:      -Wall
+  exposed-modules:  Data.Fix
 
-  ghc-options: -Wall
+  ghc-options: -Wno-trustworthy-safe
+  ghc-options:
+      -Wincomplete-uni-patterns -Wincomplete-record-updates
+      -Wredundant-constraints -Widentities -Wmissing-export-lists
 
-  Exposed-modules: 
-      Data.Fix
+  build-depends:
+    , base      >=4.12.0.0 && <4.21
+    , deepseq   >=1.4.4.0  && <1.6
+    , hashable  >=1.4.4.0  && <1.6
diff --git a/src/Data/Fix.hs b/src/Data/Fix.hs
--- a/src/Data/Fix.hs
+++ b/src/Data/Fix.hs
@@ -1,13 +1,21 @@
-{-# Language
-        FlexibleContexts,
-        UndecidableInstances,
-        TypeSynonymInstances,
-        DeriveGeneric,
-        DeriveDataTypeable,
-        StandaloneDeriving #-}
--- | Fix-point type. It allows to define generic recurion schemes.
---
--- > Fix f = f (Fix f)
+{-# LANGUAGE CPP                       #-}
+{-# LANGUAGE DeriveDataTypeable        #-}
+{-# LANGUAGE DeriveGeneric             #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE RankNTypes                #-}
+{-# LANGUAGE Trustworthy               #-}
+
+-- needed for Data instance
+{-# LANGUAGE UndecidableInstances      #-}
+
+#define HAS_POLY_TYPEABLE MIN_VERSION_base(4,7,0)
+#define HAS_QUANTIFIED_FUNCTOR_CLASSES MIN_VERSION_base(4,18,0)
+
+#if HAS_POLY_TYPEABLE
+{-# LANGUAGE StandaloneDeriving        #-}
+#endif
+
+-- | Fixed points of a functor.
 --
 -- Type @f@ should be a 'Functor' if you want to use
 -- simple recursion schemes or 'Traversable' if you want to
@@ -16,103 +24,468 @@
 -- You can imagine that a non-recursive function
 -- holds values of the previous iteration.
 --
--- Little example:
+-- An example:
 --
--- > type List a = Fix (L a)
--- >
--- > data L a b = Nil | Cons a b
--- >
--- > instance Functor (L a) where
--- >    fmap f x = case x of
--- >        Nil      -> Nil
--- >        Cons a b -> Cons a (f b)
--- >
--- > length :: List a -> Int
--- > length = cata $ \x -> case x of
--- >    Nil      -> 0
--- >    Cons _ n -> n + 1
--- >
--- > sum :: Num a => List a -> a
--- > sum = cata $ \x -> case x of
--- >    Nil      -> 0
--- >    Cons a s -> a + s
-
+-- First we define a base functor. The arguments @b@ are recursion points.
+--
+-- >>> data ListF a b = Nil | Cons a b deriving (Show, Functor)
+--
+-- The list is then a fixed point of 'ListF'
+--
+-- >>> type List a = Fix (ListF a)
+--
+-- We can write @length@ function. Note that the function we give
+-- to 'foldFix' is not recursive. Instead the results
+-- of recursive calls are in @b@ positions, and we need to deal
+-- only with one layer of the structure.
+--
+-- >>> :{
+-- let length :: List a -> Int
+--     length = foldFix $ \x -> case x of
+--         Nil      -> 0
+--         Cons _ n -> n + 1
+-- :}
+--
+-- If you already have recursive type, like '[Int]',
+-- you can first convert it to `Fix (ListF a)` and then `foldFix`.
+-- Alternatively you can use @recursion-schemes@ combinators
+-- which work directly on recursive types.
+--
 module Data.Fix (
-    Fix(..)
-    -- * Simple recursion
-    -- | Type @f@ should be a 'Functor'. They transform
-    -- non-recursive functions to recursive ones.
-    , cata
-    , ana
-    , hylo
-    , (~>)
-    -- * Monadic recursion
-    -- | Type @f@ should be a 'Traversable'.
-    , cataM
-    , anaM
-    , hyloM
-    )
-where
+    -- * Fix
+    Fix (..),
+    hoistFix,
+    hoistFix',
+    foldFix,
+    unfoldFix,
+    wrapFix,
+    unwrapFix,
+    -- * Mu - least fixed point
+    Mu (..),
+    hoistMu,
+    foldMu,
+    unfoldMu,
+    wrapMu,
+    unwrapMu,
+    -- * Nu - greatest fixed point
+    Nu (..),
+    hoistNu,
+    foldNu,
+    unfoldNu,
+    wrapNu,
+    unwrapNu,
+    -- * Refolding
+    refold,
+    -- * Monadic variants
+    foldFixM,
+    unfoldFixM,
+    refoldM,
+    -- * Deprecated aliases
+    cata, ana, hylo,
+    cataM, anaM, hyloM,
+) where
 
-import GHC.Generics
-import Control.Applicative
+-- Explicit imports help dodge unused imports warnings,
+-- as we say what we want from Prelude
+import Data.Traversable (Traversable (..))
+import Prelude (Eq (..), Functor (..), Monad (..), Ord (..), Read (..), Show (..), showParen, showString, ($), (.), (=<<))
+
+#ifdef __GLASGOW_HASKELL__
+#if !HAS_POLY_TYPEABLE
+import Prelude (const, error, undefined)
+#endif
+#endif
+
+import Control.Monad        (liftM)
+import Data.Function        (on)
+import Data.Functor.Classes (Eq1, Ord1, Read1, Show1, readsPrec1, showsPrec1)
+import Data.Hashable        (Hashable (..))
+import Data.Hashable.Lifted (Hashable1, hashWithSalt1)
+import Data.Typeable        (Typeable)
+import GHC.Generics         (Generic)
+import Text.Read            (Lexeme (Ident), Read (..), lexP, parens, prec, readS_to_Prec, step)
+
+#if MIN_VERSION_deepseq(1,4,3)
+import Control.DeepSeq (NFData (..), NFData1, rnf1)
+#endif
+
+#if HAS_POLY_TYPEABLE
+import Data.Data (Data)
+#else
 import Data.Data
-import Data.Function (on)
-import Data.Traversable
+#endif
 
+#if !HAS_QUANTIFIED_FUNCTOR_CLASSES
+import Data.Functor.Classes (compare1, eq1)
+#endif
+
+-- $setup
+-- >>> :set -XDeriveFunctor
+-- >>> import Prelude
+-- >>> import Data.Functor.Classes
+-- >>> data ListF a b = Nil | Cons a b deriving (Show, Functor)
+--
+-- >>> :{
+-- >>> instance Show a => Show1 (ListF a) where
+-- >>>     liftShowsPrec _  _ d Nil        = showString "Nil"
+-- >>>     liftShowsPrec sp _ d (Cons a b) = showParen (d > 10) $ showString "Cons " . showsPrec 11 a . showChar ' ' . sp 11 b
+-- >>> :}
+--
+-- >>> :{
+-- >>> let elimListF n c Nil        = 0
+-- >>>     elimListF n c (Cons a b) = c a b
+-- >>> :}
+
+-------------------------------------------------------------------------------
+-- Fix
+-------------------------------------------------------------------------------
+
 -- | A fix-point type.
-newtype Fix f = Fix { unFix :: f (Fix f) } deriving (Generic, Typeable)
+newtype Fix f = Fix { unFix :: f (Fix f) }
+  deriving (Generic)
+
+-- | Change base functor in 'Fix'.
+hoistFix :: Functor f => (forall a. f a -> g a) -> Fix f -> Fix g
+hoistFix nt = go where go (Fix f) = Fix (nt (fmap go f))
+
+-- | Like 'hoistFix' but 'fmap'ping over @g@.
+hoistFix' :: Functor g => (forall a. f a -> g a) -> Fix f -> Fix g
+hoistFix' nt = go where go (Fix f) = Fix (fmap go (nt f))
+
+-- | Fold 'Fix'.
+--
+-- >>> let fp = unfoldFix (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)
+-- >>> foldFix (elimListF 0 (+)) fp
+-- 6
+--
+foldFix :: Functor f => (f a -> a) -> Fix f -> a
+foldFix f = go where go = f . fmap go . unFix
+
+-- | Unfold 'Fix'.
+--
+-- >>> unfoldFix (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)
+-- Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix (Cons 3 (Fix Nil))))))))
+--
+unfoldFix :: Functor f => (a -> f a) -> a -> Fix f
+unfoldFix f = go where go = Fix . fmap go . f
+
+-- | Wrap 'Fix'.
+--
+-- >>> let x = unfoldFix (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
+-- >>> wrapFix (Cons 10 x)
+-- Fix (Cons 10 (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil))))))))
+--
+-- @since 0.3.2
+--
+wrapFix :: f (Fix f) -> Fix f
+wrapFix = Fix
+
+-- | Unwrap 'Fix'.
+--
+-- >>> let x = unfoldFix (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
+-- >>> unwrapFix x
+-- Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil)))))
+--
+-- @since 0.3.2
+--
+unwrapFix :: Fix f -> f (Fix f)
+unwrapFix = unFix
+
+-------------------------------------------------------------------------------
+-- Functor instances
+-------------------------------------------------------------------------------
+
+instance Eq1 f => Eq (Fix f) where
+#if HAS_QUANTIFIED_FUNCTOR_CLASSES
+    Fix a == Fix b = a == b
+#else
+    Fix a == Fix b = eq1 a b
+#endif
+
+instance Ord1 f => Ord (Fix f) where
+#if HAS_QUANTIFIED_FUNCTOR_CLASSES
+    compare (Fix a) (Fix b) = compare a b
+    min (Fix a) (Fix b) = Fix (min a b)
+    max (Fix a) (Fix b) = Fix (max a b)
+    Fix a >= Fix b = a >= b
+    Fix a > Fix b = a > b
+    Fix a < Fix b = a < b
+    Fix a <= Fix b = a <= b
+#else
+    compare (Fix a) (Fix b) = compare1 a b
+#endif
+
+instance Show1 f => Show (Fix f) where
+    showsPrec d (Fix a) =
+        showParen (d >= 11)
+            $ showString "Fix "
+            . showsPrec1 11 a
+
+#ifdef __GLASGOW_HASKELL__
+instance Read1 f => Read (Fix f) where
+    readPrec = parens $ prec 10 $ do
+        Ident "Fix" <- lexP
+        fmap Fix (step (readS_to_Prec readsPrec1))
+#endif
+
+-------------------------------------------------------------------------------
+-- hashable
+-------------------------------------------------------------------------------
+
+instance Hashable1 f => Hashable (Fix f) where
+#if MIN_VERSION_hashable(1,5,0)
+    hash (Fix x) = hash x
+    hashWithSalt salt (Fix x) = hashWithSalt salt x
+#else
+    hashWithSalt salt = hashWithSalt1 salt . unFix
+#endif
+
+-------------------------------------------------------------------------------
+-- deepseq
+-------------------------------------------------------------------------------
+
+#if MIN_VERSION_deepseq(1,4,3)
+instance NFData1 f => NFData (Fix f) where
+#if MIN_VERSION_deepseq(1,5,0)
+    rnf (Fix a) = rnf a 
+#else
+    rnf = rnf1 . unFix
+#endif
+#endif
+
+-------------------------------------------------------------------------------
+-- Typeable and Data
+-------------------------------------------------------------------------------
+
+#ifdef __GLASGOW_HASKELL__
+#if HAS_POLY_TYPEABLE
+deriving instance Typeable Fix
 deriving instance (Typeable f, Data (f (Fix f))) => Data (Fix f)
+#else
+instance Typeable1 f => Typeable (Fix f) where
+   typeOf t = mkTyConApp fixTyCon [typeOf1 (undefined `asArgsTypeOf` t)]
+     where asArgsTypeOf :: f a -> Fix f -> f a
+           asArgsTypeOf = const
 
--- standard instances
+fixTyCon :: TyCon
+#if MIN_VERSION_base(4,4,0)
+fixTyCon = mkTyCon3 "recursion-schemes" "Data.Functor.Foldable" "Fix"
+#else
+fixTyCon = mkTyCon "Data.Functor.Foldable.Fix"
+#endif
+{-# NOINLINE fixTyCon #-}
 
-instance Show (f (Fix f)) => Show (Fix f) where
-    showsPrec n x = showParen (n > 10) $ \s ->
-        "Fix " ++ showsPrec 11 (unFix x) s
+instance (Typeable1 f, Data (f (Fix f))) => Data (Fix f) where
+  gfoldl f z (Fix a) = z Fix `f` a
+  toConstr _ = fixConstr
+  gunfold k z c = case constrIndex c of
+    1 -> k (z (Fix))
+    _ -> error "gunfold"
+  dataTypeOf _ = fixDataType
 
-instance Read (f (Fix f)) => Read (Fix f) where
-    readsPrec d = readParen (d > 10) $ \r ->
-        [(Fix m, t) | ("Fix", s) <- lex r, (m, t) <- readsPrec 11 s]
+fixConstr :: Constr
+fixConstr = mkConstr fixDataType "Fix" [] Prefix
 
-instance Eq (f (Fix f)) => Eq (Fix f) where
-    (==) = (==) `on` unFix
+fixDataType :: DataType
+fixDataType = mkDataType "Data.Functor.Foldable.Fix" [fixConstr]
+#endif
+#endif
 
-instance Ord (f (Fix f)) => Ord (Fix f) where
-    compare = compare `on` unFix
+-------------------------------------------------------------------------------
+-- Mu
+-------------------------------------------------------------------------------
 
+-- | Least fixed point. Efficient folding.
+newtype Mu f = Mu { unMu :: forall a. (f a -> a) -> a }
 
--- recursion
+instance (Functor f, Eq1 f) => Eq (Mu f) where
+    (==) = (==) `on` foldMu Fix
 
+instance (Functor f, Ord1 f) => Ord (Mu f) where
+    compare = compare `on` foldMu Fix
+
+instance (Functor f, Show1 f) => Show (Mu f) where
+    showsPrec d f = showParen (d > 10) $
+        showString "unfoldMu unFix " . showsPrec 11 (foldMu Fix f)
+
+#ifdef __GLASGOW_HASKELL__
+instance (Functor f, Read1 f) => Read (Mu f) where
+    readPrec = parens $ prec 10 $ do
+        Ident "unfoldMu" <- lexP
+        Ident "unFix" <- lexP
+        fmap (unfoldMu unFix) (step readPrec)
+#endif
+
+-- | Change base functor in 'Mu'.
+hoistMu :: (forall a. f a -> g a) -> Mu f -> Mu g
+hoistMu n (Mu mk) = Mu $ \roll -> mk (roll . n)
+
+-- | Fold 'Mu'.
+--
+-- >>> let mu = unfoldMu (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)
+-- >>> foldMu (elimListF 0 (+)) mu
+-- 6
+foldMu :: (f a -> a) -> Mu f -> a
+foldMu f (Mu mk) = mk f
+
+-- | Unfold 'Mu'.
+--
+-- >>> unfoldMu (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)
+-- unfoldMu unFix (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix (Cons 3 (Fix Nil)))))))))
+unfoldMu :: Functor f => (a -> f a) -> a -> Mu f
+unfoldMu f x = Mu $ \mk -> refold mk f x
+
+-- | Wrap 'Mu'.
+--
+-- >>> let x = unfoldMu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
+-- >>> wrapMu (Cons 10 x)
+-- unfoldMu unFix (Fix (Cons 10 (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil)))))))))
+--
+-- @since 0.3.2
+--
+wrapMu :: Functor f => f (Mu f) -> Mu f
+wrapMu fx = Mu $ \f -> f (fmap (foldMu f) fx)
+
+-- | Unwrap 'Mu'.
+--
+-- >>> let x = unfoldMu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
+-- >>> unwrapMu x
+-- Cons 0 (unfoldMu unFix (Fix (Cons 1 (Fix (Cons 2 (Fix Nil))))))
+--
+-- @since 0.3.2
+--
+unwrapMu :: Functor f => Mu f -> f (Mu f)
+unwrapMu = foldMu (fmap wrapMu)
+
+-------------------------------------------------------------------------------
+-- Nu
+-------------------------------------------------------------------------------
+
+-- | Greatest fixed point. Efficient unfolding.
+data Nu f = forall a. Nu (a -> f a) a
+
+instance (Functor f, Eq1 f) => Eq (Nu f) where
+    (==) = (==) `on` foldNu Fix
+
+instance (Functor f, Ord1 f) => Ord (Nu f) where
+    compare = compare `on` foldNu Fix
+
+instance (Functor f, Show1 f) => Show (Nu f) where
+    showsPrec d f = showParen (d > 10) $
+        showString "unfoldNu unFix " . showsPrec 11 (foldNu Fix f)
+
+#ifdef __GLASGOW_HASKELL__
+instance (Functor f, Read1 f) => Read (Nu f) where
+    readPrec = parens $ prec 10 $ do
+        Ident "unfoldNu" <- lexP
+        Ident "unFix" <- lexP
+        fmap (unfoldNu unFix) (step readPrec)
+#endif
+
+-- | Change base functor in 'Nu'.
+hoistNu :: (forall a. f a -> g a) -> Nu f -> Nu g
+hoistNu n (Nu next seed) = Nu (n . next) seed
+
+-- | Fold 'Nu'.
+--
+-- >>> let nu = unfoldNu (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)
+-- >>> foldNu (elimListF 0 (+)) nu
+-- 6
+--
+foldNu :: Functor f => (f a -> a) -> Nu f -> a
+foldNu f (Nu next seed) = refold f next seed
+
+-- | Unfold 'Nu'.
+--
+-- >>> unfoldNu (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)
+-- unfoldNu unFix (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix (Cons 3 (Fix Nil)))))))))
+unfoldNu :: (a -> f a) -> a -> Nu f
+unfoldNu = Nu
+
+-- | Wrap 'Nu'.
+--
+-- >>> let x = unfoldNu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
+-- >>> wrapNu (Cons 10 x)
+-- unfoldNu unFix (Fix (Cons 10 (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil)))))))))
+--
+-- @since 0.3.2
+--
+wrapNu :: Functor f => f (Nu f) -> Nu f
+wrapNu = unfoldNu (fmap unwrapNu)
+
+-- | Unwrap 'Nu'.
+--
+-- >>> let x = unfoldNu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
+-- >>> unwrapNu x
+-- Cons 0 (unfoldNu unFix (Fix (Cons 1 (Fix (Cons 2 (Fix Nil))))))
+--
+-- @since 0.3.2
+--
+unwrapNu :: Functor f => Nu f -> f (Nu f)
+unwrapNu (Nu f x) = fmap (Nu f) (f x)
+
+-------------------------------------------------------------------------------
+-- refold
+-------------------------------------------------------------------------------
+
+-- | Refold one recursive type into another, one layer at the time.
+--
+refold :: Functor f => (f b -> b) -> (a -> f a) -> a -> b
+refold f g = h where h = f . fmap h . g
+
+-------------------------------------------------------------------------------
+-- Monadic variants
+-------------------------------------------------------------------------------
+
+-- | Monadic 'foldFix'.
+--
+foldFixM:: (Monad m, Traversable t)
+    => (t a -> m a) -> Fix t -> m a
+foldFixM f = go where go = (f =<<) . mapM go . unFix
+
+-- | Monadic anamorphism.
+unfoldFixM :: (Monad m, Traversable t)
+    => (a -> m (t a)) -> (a -> m (Fix t))
+unfoldFixM f = go where go = liftM Fix . (mapM go =<<) . f
+
+-- | Monadic hylomorphism.
+refoldM :: (Monad m, Traversable t)
+    => (t b -> m b) -> (a -> m (t a)) -> (a -> m b)
+refoldM phi psi = go where go = (phi =<<) . (mapM go =<<) . psi
+
+-------------------------------------------------------------------------------
+-- Deprecated aliases
+-------------------------------------------------------------------------------
+
 -- | Catamorphism or generic function fold.
 cata :: Functor f => (f a -> a) -> (Fix f -> a)
-cata f = f . fmap (cata f) . unFix
+cata = foldFix
+{-# DEPRECATED cata "Use foldFix" #-}
 
 -- | Anamorphism or generic function unfold.
 ana :: Functor f => (a -> f a) -> (a -> Fix f)
-ana f = Fix . fmap (ana f) . f
+ana = unfoldFix
+{-# DEPRECATED ana "Use unfoldFix" #-}
 
 -- | Hylomorphism is anamorphism followed by catamorphism.
 hylo :: Functor f => (f b -> b) -> (a -> f a) -> (a -> b)
-hylo phi psi = cata phi . ana psi
-
--- | Infix version of @hylo@.
-(~>) :: Functor f => (a -> f a) -> (f b -> b) -> (a -> b)
-psi ~> phi = phi . fmap (hylo phi psi) . psi
-
--- monadic recursion
+hylo = refold
+{-# DEPRECATED hylo "Use refold" #-}
 
 -- | Monadic catamorphism.
-cataM :: (Applicative m, Monad m, Traversable t)
+cataM :: (Monad m, Traversable t)
     => (t a -> m a) -> Fix t -> m a
-cataM f = (f =<<) . traverse (cataM f) . unFix
+cataM = foldFixM
+{-# DEPRECATED cataM "Use foldFixM" #-}
 
 -- | Monadic anamorphism.
-anaM :: (Applicative m, Monad m, Traversable t)
+anaM :: (Monad m, Traversable t)
     => (a -> m (t a)) -> (a -> m (Fix t))
-anaM f = fmap Fix . (traverse (anaM f) =<<) . f
+anaM = unfoldFixM
+{-# DEPRECATED anaM "Use unfoldFixM" #-}
 
 -- | Monadic hylomorphism.
-hyloM :: (Applicative m, Monad m, Traversable t)
+hyloM :: (Monad m, Traversable t)
     => (t b -> m b) -> (a -> m (t a)) -> (a -> m b)
-hyloM phi psi = (cataM phi =<<) . anaM psi
-
+hyloM = refoldM
+{-# DEPRECATED hyloM "Use refoldM" #-}
