diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,18 @@
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/).
 
+## 0.4.0.1 - 2020-12-08
+### Changed
+- updated explanation of differences from `recursion-schemes`
+- updated comments and parameter names in metamorphisms
+
+## 0.4.0.0 – 2020–12-08
+### Added
+- more example algebras
+### Changed
+- `while` is generalized and now called `definedOrInput`
+- `split` renamed to `diagonal`
+
 ## 0.3.2.0 – 2020–06-01
 ### Added
 - `zipAlgebraMs`
diff --git a/src/Yaya/Applied.hs b/src/Yaya/Applied.hs
--- a/src/Yaya/Applied.hs
+++ b/src/Yaya/Applied.hs
@@ -44,14 +44,25 @@
 takeUpTo
   :: (Recursive (->) n Maybe, Projectable (->) s (XNor a), Steppable (->) l (XNor a))
   => n -> s -> l
-takeUpTo = cata (lowerDay (embed . takeAvailable))
+takeUpTo = cata2 (embed . takeAvailable)
 
 -- | Extracts _exactly_ @n@ elements from the infinite stream @s@.
 take
   :: (Recursive (->) n Maybe, Projectable (->) s ((,) a), Steppable (->) l (XNor a))
   => n -> s -> l
-take = cata (lowerDay (embed . takeAnother))
+take = cata2 (embed . takeAnother)
 
+-- | Extracts the element at a finite index of an infinite sequence (a `!!` that
+--   can't fail).
+at :: (Recursive (->) n Maybe, Projectable (->) s ((,) a)) => n -> s -> a
+at = cata2 takeNext
+
+-- | Extracts the element at a finite index of a (co)list (a `!!` that fails
+--   with `Nothing`).
+atMay
+  :: (Recursive (->) n Maybe, Projectable (->) s (XNor a)) => n -> s -> Maybe a
+atMay = cata2 maybeTakeNext
+
 -- | Turns part of a structure inductive, so it can be analyzed, without forcing
 --   the entire tree.
 maybeReify
@@ -91,7 +102,7 @@
 
 -- | Creates an infinite stream of the provided value.
 constantly :: Corecursive (->) t ((,) a) => a -> t
-constantly = ana split
+constantly = ana diagonal
 
 -- | Lops off the branches of the tree below a certain depth, turning a
 --   potentially-infinite structure into a finite one. Like a generalized
@@ -99,4 +110,4 @@
 truncate
   :: (Recursive (->) n Maybe, Projectable (->) t f, Steppable (->) u (FreeF f ()), Functor f)
   => n -> t -> u
-truncate = cata (lowerDay (embed . truncate'))
+truncate = cata2 (embed . truncate')
diff --git a/src/Yaya/Fold/Common.hs b/src/Yaya/Fold/Common.hs
--- a/src/Yaya/Fold/Common.hs
+++ b/src/Yaya/Fold/Common.hs
@@ -43,7 +43,12 @@
 -- NB: It seems like this could be some more general notion of this, like
 --        size :: (Foldable f, Semiring a) => f a -> a
 --        size = foldr (+) one
--- | When folded, returns the number ef nodes in the data structure.
+-- | When folded, returns the number of nodes in the data structure.
+--
+--  __NB__: This is /not/ the same as the length when applied to a list. I.e.,
+--          @`length` xs + 1 == `cata` `size` xs@, because this is counting the
+--          nodes of the structure (how many `Neither`s and `Both`s), not how
+--          many elements (which would be equivalent to only counting `Both`s).
 size :: Foldable f => f Natural -> Natural
 size = foldr (+) 1
 
@@ -52,16 +57,14 @@
 toRight :: Identity b -> Either a b
 toRight = Right . runIdentity
 
--- | Returns the last 'Just' result.
-while :: (a -> Maybe a) -> a -> Either a a
-while f a = maybe (Left a) Right $ f a
+-- | Captures the input value if the application was undefined.
+definedOrInput :: (a -> Maybe b) -> a -> Either a b
+definedOrInput f a = maybe (Left a) Right $ f a
 
 -- | Collapses a `Yaya.Zoo.Partial` structure to a value (probably requiring
 --   unsafe instances).
 fromEither :: Either a a -> a
-fromEither = \case
-  Left a  -> a
-  Right a -> a
+fromEither = either id id
 
 -- | Generates an infinite structure from an arbitrary seed.
 never :: a -> Identity a
@@ -83,15 +86,26 @@
   Day Nothing  _ _ -> Neither
   Day (Just x) t f -> fmap (f x) t
 
+takeNext :: Day Maybe ((,) a) a -> a
+takeNext = \case
+  Day Nothing  (h, _) _ -> h
+  Day (Just x) (_, t) f -> f x t
+
+maybeTakeNext :: Day Maybe (XNor a) (Maybe a) -> Maybe a
+maybeTakeNext = \case
+  Day Nothing  (Both h _) _ -> Just h
+  Day (Just x) (Both _ t) f -> f x t
+  Day _        Neither    _ -> Nothing
+
 truncate' :: Functor f => Day Maybe f a -> FreeF f () a
 truncate' = \case
   Day Nothing  _  _ -> Pure ()
   Day (Just n) fa f -> Free (fmap (f n) fa)
 
 -- | Converts a single value into a tuple with the same value on both sides.
---   > x &&& y = (x *** y) . split
-split :: a -> (a, a)
-split x = (x, x)
+--   > x &&& y = (x *** y) . diagonal
+diagonal :: a -> (a, a)
+diagonal x = (x, x)
 
 -- * sequence generators
 --
diff --git a/src/Yaya/Retrofit.hs b/src/Yaya/Retrofit.hs
--- a/src/Yaya/Retrofit.hs
+++ b/src/Yaya/Retrofit.hs
@@ -49,6 +49,22 @@
        , recursiveShowsPrec
        )
 
+#if MIN_VERSION_template_haskell(2, 17, 0)
+type TyVarBndr' = TyVarBndr ()
+#else
+type TyVarBndr' = TyVarBndr
+#endif
+
+#if MIN_VERSION_template_haskell(2, 17, 0)
+-- provided via TH in newer versions
+#else
+kindedTV :: Name -> Kind -> TyVarBndr'
+kindedTV n k = PlainTV n k
+
+plainTV :: Name -> TyVarBndr'
+plainTV n = PlainTV n
+#endif
+
 -- | Extract a pattern functor and relevant instances from a simply recursive type.
 --
 -- /e.g./
@@ -161,13 +177,13 @@
                           Datatype        -> False
                           Newtype         -> False
 
-    toTyVarBndr :: Type -> Maybe TyVarBndr
-    toTyVarBndr (VarT n)          = pure $ PlainTV n
-    toTyVarBndr (SigT (VarT n) k) = pure $ KindedTV n k
+    toTyVarBndr :: Type -> Maybe TyVarBndr'
+    toTyVarBndr (VarT n)          = pure $ plainTV n
+    toTyVarBndr (SigT (VarT n) k) = pure $ kindedTV n k
     toTyVarBndr _                 = Nothing
 
 makePrimForDI'
-  :: PatternFunctorRules -> Bool -> Name -> [TyVarBndr] -> [ConstructorInfo] -> Q [Dec]
+  :: PatternFunctorRules -> Bool -> Name -> [TyVarBndr'] -> [ConstructorInfo] -> Q [Dec]
 makePrimForDI' rules isNewtype tyName vars cons = do
     -- variable parameters
     let vars' = map VarT (typeVars vars)
@@ -180,7 +196,7 @@
     let r = VarT rName
    
     -- Vars
-    let varsF = vars ++ [PlainTV rName]
+    let varsF = vars ++ [plainTV rName]
 
     -- #33
     cons' <- traverse (conTypeTraversal resolveTypeSynonyms) cons
@@ -199,7 +215,7 @@
           where
             deriveds =
 -- TH 2.12.O means GHC 8.2.1, otherwise, we work back to GHC 8.0.1
-#if MIN_VERSION_template_haskell(2,12,0)
+#if MIN_VERSION_template_haskell(2, 12, 0)
               pure $ DerivClause Nothing
 #endif
               [ ConT functorTypeName
@@ -289,7 +305,7 @@
 -------------------------------------------------------------------------------
 
 -- | Extract type variables
-typeVars :: [TyVarBndr] -> [Name]
+typeVars :: [TyVarBndr'] -> [Name]
 typeVars = map tvName
 
 -- | Apply arguments to a type constructor.
diff --git a/yaya.cabal b/yaya.cabal
--- a/yaya.cabal
+++ b/yaya.cabal
@@ -1,5 +1,5 @@
 name:                yaya
-version:             0.3.2.0
+version:             0.4.1.0
 synopsis:            Total recursion schemes.
 description:         Recursion schemes allow you to separate recursion from your
                      business logic – making your own operations simpler, more
