diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,25 @@
 The format is based on [Keep a Changelog 1.1](https://keepachangelog.com/en/1.1.0/),
 and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/).
 
+## [1.0.0.0] - 2026-04-22
+
+### Removed
+
+- dependency on `lens`
+- all optics-related bits (`AlgebraPrism`, `BialgebraIso`, etc.) – most are now available in the `yaya-lens` package
+- constructors and fields for fixed-points (`Mu`, `Nu`, `Fix`, `unFix`, `Cofix`, and `unCofix`)
+
+### Changed
+
+- generalized type of `distEnvT`
+
+### Added
+
+- `Embed` and `Project` patterns for exhaustive nested matching on recursive types
+- `distCofreeT`, `seqFreeF`, `seqFreeT`, and `futu` are now safe and correspondingly moved here from `yaya-unsafe`
+- `isNeither` helper for `XNor`
+- `qualifiedRules` for retrofitting without mangling names
+
 ## [0.7.0.0] - 2026-01-18
 
 ### Added
@@ -44,13 +63,13 @@
 
 ## [0.5.0.0] -
 
-## [0.4.2.3] – 2024–01–11
+## [0.4.2.3] - 2024-01-11
 
 ### Changed
 
 - added CPP to support GHC 9.8
 
-## [0.4.2.2] – 2023–12–21
+## [0.4.2.2] - 2023-12-21
 
 ### Changed
 
@@ -69,14 +88,14 @@
 
 Unknown changes.
 
-## [0.4.0.1] – 2020–12–08
+## [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
+## [0.4.0.0] - 2020-12-08
 
 ### Added
 
@@ -87,62 +106,62 @@
 - `while` is generalized and now called `definedOrInput`
 - `split` renamed to `diagonal`
 
-## [0.3.2.0] – 2020–06–01
+## [0.3.2.0] - 2020-06-01
 
 ### Added
 
 - `zipAlgebraMs`
 
-## [0.3.1.2] – 2020–05–18
+## [0.3.1.2] - 2020-05-18
 
 ### Added
 
 - `HFunctor` instances
 
-## [0.3.1.1] – 2020–05–18
+## [0.3.1.1] - 2020-05-18
 
 ### Changed
 
 - Turned on StrictData
 
-## [0.3.1.0] – 2020–05–18
+## [0.3.1.0] - 2020-05-18
 
 ### Added
 
 - Copied Kmett's auto-extraction of pattern functors
 
-## [0.3.0.0] – 2020–05–14
+## [0.3.0.0] - 2020-05-14
 
 ### Changed
 
 - introduced minimal poly-kinding of type classes
 
-## [0.2.1.3] – 2020–05–14
+## [0.2.1.3] - 2020-05-14
 
 ### Changed
 
 - enabled and fixed warnings
 
-## [0.2.1.2] – 2019–11–08
+## [0.2.1.2] - 2019-11-08
 
 ### Changed
 
 - improved documentation
 
-## [0.2.1.1] – 2019–11–08
+## [0.2.1.1] - 2019-11-08
 
 ### Added
 
 - documentation explaining limitations of `Mu`
 - tests for `law_cataCompose` (which bumps the yaya-hedgehog dependency for tests)
 
-## [0.2.1.0] – 2019–01–08
+## [0.2.1.0] - 2019-01-08
 
 ### Added
 
 - exports of type class methods via `Yaya.Retrofit`
 
-## [0.2.0.0] – 2019–01–08
+## [0.2.0.0] - 2019-01-08
 
 ### Added
 
@@ -154,16 +173,17 @@
 - moved `DFunctor` and `HFunctor` to a new `Yaya.Functor` module
 - renamed `cursiveIso` to `steppableIso`
 
-## [0.1.0.0] – 2019–01–04
+## [0.1.0.0] - 2019-01-04
 
 ### Added
 
 - everything (this is the initial release)
 
-[0.7.0.0]: https://github.com/sellout/no-recursion/compare/v3.2.3...v4.0.0
-[0.6.2.3]: https://github.com/sellout/no-recursion/compare/v3.2.1...v3.2.3
-[0.6.2.2]: https://github.com/sellout/no-recursion/compare/v3.2.0...v3.2.1
-[0.6.2.0]: https://github.com/sellout/no-recursion/compare/v3.1.0...v3.2.0
-[0.6.1.0]: https://github.com/sellout/no-recursion/compare/v3.0.0...v3.1.0
-[0.6.0.0]: https://github.com/sellout/no-recursion/compare/v1.0.0...v3.0.0
+[1.0.0.0]: https://github.com/sellout/yaya/compare/v4.0.0...v5.0.0
+[0.7.0.0]: https://github.com/sellout/yaya/compare/v3.2.3...v4.0.0
+[0.6.2.3]: https://github.com/sellout/yaya/compare/v3.2.1...v3.2.3
+[0.6.2.2]: https://github.com/sellout/yaya/compare/v3.2.0...v3.2.1
+[0.6.2.0]: https://github.com/sellout/yaya/compare/v3.1.0...v3.2.0
+[0.6.1.0]: https://github.com/sellout/yaya/compare/v3.0.0...v3.1.0
+[0.6.0.0]: https://github.com/sellout/yaya/compare/v1.0.0...v3.0.0
 [0.5.2.1]: https://github.com/sellout/yaya/releases/tag/v1.0.0
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,17 +1,12 @@
 -- __NB__: `custom-setup` doesn’t have any way to specify extensions or options,
 --         so any we want need to be specified here.
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE PackageImports #-}
 {-# LANGUAGE Unsafe #-}
 {-# LANGUAGE NoImplicitPrelude #-}
-#if MIN_VERSION_GLASGOW_HASKELL(8, 0, 0, 0)
 {-# OPTIONS_GHC -Weverything #-}
 -- Warns even when `Unsafe` is explicit, not inferred. See
 -- https://gitlab.haskell.org/ghc/ghc/-/issues/16689
 {-# OPTIONS_GHC -Wno-unsafe #-}
-#else
-{-# OPTIONS_GHC -Wall #-}
-#endif
 
 module Main (main) where
 
diff --git a/docs/license-report.md b/docs/license-report.md
--- a/docs/license-report.md
+++ b/docs/license-report.md
@@ -9,39 +9,36 @@
 | Name | Version | [SPDX](https://spdx.org/licenses/) License Id | Description | Also depended upon by |
 | --- | --- | --- | --- | --- |
 | **`base`** | [`4.20.0.0`](http://hackage.haskell.org/package/base-4.20.0.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/base-4.20.0.0/src/LICENSE) | Core data structures and operations | *(core library)* |
-| `comonad` | [`5.0.10`](http://hackage.haskell.org/package/comonad-5.0.10) | [`BSD-3-Clause`](http://hackage.haskell.org/package/comonad-5.0.10/src/LICENSE) | Comonads | `adjunctions`, `bifunctors`, `free`, `invariant`, `kan-extensions`, `lens`, `profunctors`, `semigroupoids` |
+| `comonad` | [`5.0.10`](http://hackage.haskell.org/package/comonad-5.0.10) | [`BSD-3-Clause`](http://hackage.haskell.org/package/comonad-5.0.10/src/LICENSE) | Comonads | `adjunctions`, `bifunctors`, `free`, `invariant`, `kan-extensions`, `profunctors`, `semigroupoids` |
 | `either` | [`5.0.3`](http://hackage.haskell.org/package/either-5.0.3) | [`BSD-3-Clause`](http://hackage.haskell.org/package/either-5.0.3/src/LICENSE) | Combinators for working with sums |  |
-| `free` | [`5.2`](http://hackage.haskell.org/package/free-5.2) | [`BSD-3-Clause`](http://hackage.haskell.org/package/free-5.2/src/LICENSE) | Monads for free | `adjunctions`, `kan-extensions`, `lens` |
-| `kan-extensions` | [`5.2.8`](http://hackage.haskell.org/package/kan-extensions-5.2.8) | [`BSD-3-Clause`](http://hackage.haskell.org/package/kan-extensions-5.2.8/src/LICENSE) | Kan extensions, Kan lifts, the Yoneda lemma, and (co)density (co)monads | `lens` |
-| `lens` | [`5.3.6`](http://hackage.haskell.org/package/lens-5.3.6) | [`BSD-2-Clause`](http://hackage.haskell.org/package/lens-5.3.6/src/LICENSE) | Lenses, Folds and Traversals |  |
+| `free` | [`5.2`](http://hackage.haskell.org/package/free-5.2) | [`BSD-3-Clause`](http://hackage.haskell.org/package/free-5.2/src/LICENSE) | Monads for free | `adjunctions`, `kan-extensions` |
+| `kan-extensions` | [`5.2.8`](http://hackage.haskell.org/package/kan-extensions-5.2.8) | [`BSD-3-Clause`](http://hackage.haskell.org/package/kan-extensions-5.2.8/src/LICENSE) | Kan extensions, Kan lifts, the Yoneda lemma, and (co)density (co)monads |  |
 | `no-recursion` | [`0.4.0.0`](http://hackage.haskell.org/package/no-recursion-0.4.0.0) | [`(AGPL-3.0-only WITH Universal-FOSS-exception-1.0 OR LicenseRef-commercial)`](http://hackage.haskell.org/package/no-recursion-0.4.0.0/src/LICENSE) | A GHC plugin to remove support for recursion |  |
-| `profunctors` | [`5.6.3`](http://hackage.haskell.org/package/profunctors-5.6.3) | [`BSD-3-Clause`](http://hackage.haskell.org/package/profunctors-5.6.3/src/LICENSE) | Profunctors | `adjunctions`, `either`, `free`, `invariant`, `kan-extensions`, `lens` |
-| `strict` | [`0.5.1`](http://hackage.haskell.org/package/strict-0.5.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/strict-0.5.1/src/LICENSE) | Strict data types and String IO. | `lens` |
-| **`template-haskell`** | [`2.22.0.0`](http://hackage.haskell.org/package/template-haskell-2.22.0.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/template-haskell-2.22.0.0/src/LICENSE) | Support library for Template Haskell | `OneTuple`, `bifunctors`, `bytestring`, `containers`, `exceptions`, `filepath`, `free`, `ghc`, `ghci`, `invariant`, `lens`, `os-string`, `primitive`, `reflection`, `semigroupoids`, `tagged`, `text`, `th-abstraction`, `unordered-containers` |
-| `th-abstraction` | [`0.7.2.0`](http://hackage.haskell.org/package/th-abstraction-0.7.2.0) | [`ISC`](http://hackage.haskell.org/package/th-abstraction-0.7.2.0/src/LICENSE) | Nicer interface for reified information about data types | `bifunctors`, `free`, `invariant`, `lens` |
-| **`transformers`** | [`0.6.1.1`](http://hackage.haskell.org/package/transformers-0.6.1.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/transformers-0.6.1.1/src/LICENSE) | Concrete functor and monad transformers | `StateVar`, `adjunctions`, `comonad`, `contravariant`, `distributive`, `exceptions`, `free`, `ghc`, `ghci`, `indexed-traversable`, `invariant`, `kan-extensions`, `lens`, `mtl`, `primitive`, `profunctors`, `semigroupoids`, `strict`, `transformers-base`, `transformers-compat` |
+| `profunctors` | [`5.6.3`](http://hackage.haskell.org/package/profunctors-5.6.3) | [`BSD-3-Clause`](http://hackage.haskell.org/package/profunctors-5.6.3/src/LICENSE) | Profunctors | `adjunctions`, `either`, `free`, `invariant`, `kan-extensions` |
+| `strict` | [`0.5.1`](http://hackage.haskell.org/package/strict-0.5.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/strict-0.5.1/src/LICENSE) | Strict data types and String IO. |  |
+| **`template-haskell`** | [`2.22.0.0`](http://hackage.haskell.org/package/template-haskell-2.22.0.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/template-haskell-2.22.0.0/src/LICENSE) | Support library for Template Haskell | `bifunctors`, `bytestring`, `containers`, `exceptions`, `filepath`, `free`, `ghc`, `ghci`, `invariant`, `os-string`, `semigroupoids`, `tagged`, `text`, `th-abstraction`, `unordered-containers` |
+| `th-abstraction` | [`0.7.2.0`](http://hackage.haskell.org/package/th-abstraction-0.7.2.0) | [`ISC`](http://hackage.haskell.org/package/th-abstraction-0.7.2.0/src/LICENSE) | Nicer interface for reified information about data types | `bifunctors`, `free`, `invariant` |
+| **`transformers`** | [`0.6.1.1`](http://hackage.haskell.org/package/transformers-0.6.1.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/transformers-0.6.1.1/src/LICENSE) | Concrete functor and monad transformers | `StateVar`, `adjunctions`, `comonad`, `contravariant`, `distributive`, `exceptions`, `free`, `ghc`, `ghci`, `indexed-traversable`, `invariant`, `kan-extensions`, `mtl`, `profunctors`, `semigroupoids`, `strict`, `transformers-base`, `transformers-compat` |
 
 ## Indirect transitive dependencies
 
 | Name | Version | [SPDX](https://spdx.org/licenses/) License Id | Description | Depended upon by |
 | --- | --- | --- | --- | --- |
-| `OneTuple` | [`0.4.2.1`](http://hackage.haskell.org/package/OneTuple-0.4.2.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/OneTuple-0.4.2.1/src/LICENSE) | Singleton Tuple | `indexed-traversable-instances` |
 | `StateVar` | [`1.2.2`](http://hackage.haskell.org/package/StateVar-1.2.2) | [`BSD-3-Clause`](http://hackage.haskell.org/package/StateVar-1.2.2/src/LICENSE) | State variables | `contravariant`, `invariant` |
 | `adjunctions` | [`4.4.4`](http://hackage.haskell.org/package/adjunctions-4.4.4) | [`BSD-2-Clause`](http://hackage.haskell.org/package/adjunctions-4.4.4/src/LICENSE) | Adjunctions and representable functors | `kan-extensions` |
-| **`array`** | [`0.5.7.0`](http://hackage.haskell.org/package/array-0.5.7.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/array-0.5.7.0/src/LICENSE) | Mutable and immutable arrays | `binary`, `containers`, `deepseq`, `ghc`, `ghci`, `indexed-traversable`, `invariant`, `lens`, `parallel`, `stm`, `text` |
-| `assoc` | [`1.1.1`](http://hackage.haskell.org/package/assoc-1.1.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/assoc-1.1.1/src/LICENSE) | swap and assoc: Symmetric and Semigroupy Bifunctors | `bifunctors`, `lens`, `strict`, `these` |
-| `base-orphans` | [`0.9.4`](http://hackage.haskell.org/package/base-orphans-0.9.4) | [`MIT`](http://hackage.haskell.org/package/base-orphans-0.9.4/src/LICENSE) | Backwards-compatible orphan instances for base | `lens`, `profunctors`, `semigroupoids`, `transformers-base` |
-| `bifunctors` | [`5.6.3`](http://hackage.haskell.org/package/bifunctors-5.6.3) | [`BSD-3-Clause`](http://hackage.haskell.org/package/bifunctors-5.6.3/src/LICENSE) | Bifunctors | `either`, `invariant`, `lens`, `profunctors`, `semigroupoids` |
+| **`array`** | [`0.5.7.0`](http://hackage.haskell.org/package/array-0.5.7.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/array-0.5.7.0/src/LICENSE) | Mutable and immutable arrays | `binary`, `containers`, `deepseq`, `ghc`, `ghci`, `indexed-traversable`, `invariant`, `stm`, `text` |
+| `assoc` | [`1.1.1`](http://hackage.haskell.org/package/assoc-1.1.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/assoc-1.1.1/src/LICENSE) | swap and assoc: Symmetric and Semigroupy Bifunctors | `bifunctors`, `strict`, `these` |
+| `base-orphans` | [`0.9.4`](http://hackage.haskell.org/package/base-orphans-0.9.4) | [`MIT`](http://hackage.haskell.org/package/base-orphans-0.9.4/src/LICENSE) | Backwards-compatible orphan instances for base | `profunctors`, `semigroupoids`, `transformers-base` |
+| `bifunctors` | [`5.6.3`](http://hackage.haskell.org/package/bifunctors-5.6.3) | [`BSD-3-Clause`](http://hackage.haskell.org/package/bifunctors-5.6.3/src/LICENSE) | Bifunctors | `either`, `invariant`, `profunctors`, `semigroupoids` |
 | **`binary`** | [`0.8.9.2`](http://hackage.haskell.org/package/binary-0.8.9.2) | [`BSD-3-Clause`](http://hackage.haskell.org/package/binary-0.8.9.2/src/LICENSE) | Binary serialisation for Haskell values using lazy ByteStrings | `ghc`, `ghc-boot`, `ghci`, `strict`, `text`, `these` |
-| **`bytestring`** | [`0.12.1.0`](http://hackage.haskell.org/package/bytestring-0.12.1.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/bytestring-0.12.1.0/src/LICENSE) | Fast, compact, strict and lazy byte strings with a list interface | `binary`, `filepath`, `ghc`, `ghc-boot`, `ghci`, `hashable`, `lens`, `os-string`, `strict`, `text`, `unix` |
-| `call-stack` | [`0.4.0`](http://hackage.haskell.org/package/call-stack-0.4.0) | [`MIT`](http://hackage.haskell.org/package/call-stack-0.4.0/src/LICENSE) | Use GHC call-stacks in a backward compatible way | `lens` |
-| **`containers`** | [`0.7`](http://hackage.haskell.org/package/containers-0.7) | [`BSD-3-Clause`](http://hackage.haskell.org/package/containers-0.7/src/LICENSE) | Assorted concrete container types | `adjunctions`, `bifunctors`, `binary`, `comonad`, `free`, `ghc`, `ghc-boot`, `ghc-heap`, `ghci`, `hashable`, `hpc`, `indexed-traversable`, `invariant`, `lens`, `parallel`, `semigroupoids`, `th-abstraction` |
-| `contravariant` | [`1.5.6`](http://hackage.haskell.org/package/contravariant-1.5.6) | [`BSD-3-Clause`](http://hackage.haskell.org/package/contravariant-1.5.6/src/LICENSE) | Contravariant functors | `invariant`, `kan-extensions`, `lens`, `profunctors`, `semigroupoids` |
-| **`deepseq`** | [`1.5.0.0`](http://hackage.haskell.org/package/deepseq-1.5.0.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/deepseq-1.5.0.0/src/LICENSE) | Deep evaluation of data structures | `bytestring`, `containers`, `filepath`, `ghc`, `ghc-boot`, `ghci`, `hashable`, `hpc`, `os-string`, `parallel`, `pretty`, `primitive`, `process`, `strict`, `tagged`, `text`, `these`, `time`, `unordered-containers`, `vector` |
+| **`bytestring`** | [`0.12.1.0`](http://hackage.haskell.org/package/bytestring-0.12.1.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/bytestring-0.12.1.0/src/LICENSE) | Fast, compact, strict and lazy byte strings with a list interface | `binary`, `filepath`, `ghc`, `ghc-boot`, `ghci`, `hashable`, `os-string`, `strict`, `text`, `unix` |
+| **`containers`** | [`0.7`](http://hackage.haskell.org/package/containers-0.7) | [`BSD-3-Clause`](http://hackage.haskell.org/package/containers-0.7/src/LICENSE) | Assorted concrete container types | `adjunctions`, `bifunctors`, `binary`, `comonad`, `free`, `ghc`, `ghc-boot`, `ghc-heap`, `ghci`, `hashable`, `hpc`, `indexed-traversable`, `invariant`, `semigroupoids`, `th-abstraction` |
+| `contravariant` | [`1.5.6`](http://hackage.haskell.org/package/contravariant-1.5.6) | [`BSD-3-Clause`](http://hackage.haskell.org/package/contravariant-1.5.6/src/LICENSE) | Contravariant functors | `invariant`, `kan-extensions`, `profunctors`, `semigroupoids` |
+| **`deepseq`** | [`1.5.0.0`](http://hackage.haskell.org/package/deepseq-1.5.0.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/deepseq-1.5.0.0/src/LICENSE) | Deep evaluation of data structures | `bytestring`, `containers`, `filepath`, `ghc`, `ghc-boot`, `ghci`, `hashable`, `hpc`, `os-string`, `pretty`, `process`, `strict`, `tagged`, `text`, `these`, `time`, `unordered-containers` |
 | **`directory`** | [`1.3.8.3`](http://hackage.haskell.org/package/directory-1.3.8.3) | [`BSD-3-Clause`](http://hackage.haskell.org/package/directory-1.3.8.3/src/LICENSE) | Platform-agnostic library for filesystem operations | `ghc`, `ghc-boot`, `hpc`, `process` |
-| `distributive` | [`0.6.3`](http://hackage.haskell.org/package/distributive-0.6.3) | [`BSD-3-Clause`](http://hackage.haskell.org/package/distributive-0.6.3/src/LICENSE) | Distributive functors -- Dual to Traversable | `adjunctions`, `comonad`, `free`, `kan-extensions`, `lens`, `profunctors` |
-| **`exceptions`** | [`0.10.7`](http://hackage.haskell.org/package/exceptions-0.10.7) | [`BSD-3-Clause`](http://hackage.haskell.org/package/exceptions-0.10.7/src/LICENSE) | Extensible optionally-pure exceptions | `filepath`, `free`, `ghc`, `kan-extensions`, `lens`, `os-string`, `semaphore-compat` |
-| **`filepath`** | [`1.5.2.0`](http://hackage.haskell.org/package/filepath-1.5.2.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/filepath-1.5.2.0/src/LICENSE) | Library for manipulating FilePaths in a cross platform way. | `directory`, `ghc`, `ghc-boot`, `ghci`, `hashable`, `hpc`, `lens`, `process`, `unix` |
+| `distributive` | [`0.6.3`](http://hackage.haskell.org/package/distributive-0.6.3) | [`BSD-3-Clause`](http://hackage.haskell.org/package/distributive-0.6.3/src/LICENSE) | Distributive functors -- Dual to Traversable | `adjunctions`, `comonad`, `free`, `kan-extensions`, `profunctors` |
+| **`exceptions`** | [`0.10.7`](http://hackage.haskell.org/package/exceptions-0.10.7) | [`BSD-3-Clause`](http://hackage.haskell.org/package/exceptions-0.10.7/src/LICENSE) | Extensible optionally-pure exceptions | `filepath`, `free`, `ghc`, `kan-extensions`, `os-string`, `semaphore-compat` |
+| **`filepath`** | [`1.5.2.0`](http://hackage.haskell.org/package/filepath-1.5.2.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/filepath-1.5.2.0/src/LICENSE) | Library for manipulating FilePaths in a cross platform way. | `directory`, `ghc`, `ghc-boot`, `ghci`, `hashable`, `hpc`, `process`, `unix` |
 | **`ghc`** | [`9.10.1`](http://hackage.haskell.org/package/ghc-9.10.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/ghc-9.10.1/src/LICENSE) | The GHC API | `no-recursion` |
 | **`ghc-bignum`** | [`1.3`](http://hackage.haskell.org/package/ghc-bignum-1.3) | [`BSD-3-Clause`](http://hackage.haskell.org/package/ghc-bignum-1.3/src/LICENSE) | GHC BigNum library | `ghc-internal` |
 | **`ghc-boot`** | [`9.10.1`](http://hackage.haskell.org/package/ghc-boot-9.10.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/ghc-boot-9.10.1/src/LICENSE) | Shared functionality between GHC and its boot libraries | `ghc`, `ghci` |
@@ -51,29 +48,23 @@
 | **`ghc-platform`** | [`0.1.0.0`](http://hackage.haskell.org/package/ghc-platform-0.1.0.0) |  *MISSING* | *MISSING* | `ghc-boot` |
 | **`ghc-prim`** | [`0.11.0`](http://hackage.haskell.org/package/ghc-prim-0.11.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/ghc-prim-0.11.0/src/LICENSE) | GHC primitives | *(core library)* |
 | **`ghci`** | [`9.10.1`](http://hackage.haskell.org/package/ghci-9.10.1) |  *MISSING* | *MISSING* | `ghc` |
-| `hashable` | [`1.5.1.0`](http://hackage.haskell.org/package/hashable-1.5.1.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/hashable-1.5.1.0/src/LICENSE) | A class for types that can be converted to a hash value | `lens`, `semigroupoids`, `strict`, `these`, `unordered-containers` |
+| `hashable` | [`1.5.1.0`](http://hackage.haskell.org/package/hashable-1.5.1.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/hashable-1.5.1.0/src/LICENSE) | A class for types that can be converted to a hash value | `semigroupoids`, `strict`, `these`, `unordered-containers` |
 | **`hpc`** | [`0.7.0.1`](http://hackage.haskell.org/package/hpc-0.7.0.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/hpc-0.7.0.1/src/LICENSE) | Code Coverage Library for Haskell | `ghc` |
-| `indexed-traversable` | [`0.1.4`](http://hackage.haskell.org/package/indexed-traversable-0.1.4) | [`BSD-2-Clause`](http://hackage.haskell.org/package/indexed-traversable-0.1.4/src/LICENSE) | FunctorWithIndex, FoldableWithIndex, TraversableWithIndex | `comonad`, `free`, `indexed-traversable-instances`, `lens` |
-| `indexed-traversable-instances` | [`0.1.2`](http://hackage.haskell.org/package/indexed-traversable-instances-0.1.2) | [`BSD-2-Clause`](http://hackage.haskell.org/package/indexed-traversable-instances-0.1.2/src/LICENSE) | More instances of FunctorWithIndex, FoldableWithIndex, TraversableWithIndex | `lens` |
+| `indexed-traversable` | [`0.1.4`](http://hackage.haskell.org/package/indexed-traversable-0.1.4) | [`BSD-2-Clause`](http://hackage.haskell.org/package/indexed-traversable-0.1.4/src/LICENSE) | FunctorWithIndex, FoldableWithIndex, TraversableWithIndex | `comonad`, `free` |
 | `invariant` | [`0.6.5`](http://hackage.haskell.org/package/invariant-0.6.5) | [`BSD-2-Clause`](http://hackage.haskell.org/package/invariant-0.6.5/src/LICENSE) | Haskell98 invariant functors | `kan-extensions` |
-| **`mtl`** | [`2.3.1`](http://hackage.haskell.org/package/mtl-2.3.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/mtl-2.3.1/src/LICENSE) | Monad classes for transformers, using functional dependencies | `adjunctions`, `either`, `exceptions`, `free`, `kan-extensions`, `lens` |
+| **`mtl`** | [`2.3.1`](http://hackage.haskell.org/package/mtl-2.3.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/mtl-2.3.1/src/LICENSE) | Monad classes for transformers, using functional dependencies | `adjunctions`, `either`, `exceptions`, `free`, `kan-extensions` |
 | **`os-string`** | [`2.0.2`](http://hackage.haskell.org/package/os-string-2.0.2) | [`BSD-3-Clause`](http://hackage.haskell.org/package/os-string-2.0.2/src/LICENSE) | Library for manipulating Operating system strings. | `directory`, `filepath`, `hashable`, `unix` |
-| `parallel` | [`3.3.0.0`](http://hackage.haskell.org/package/parallel-3.3.0.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/parallel-3.3.0.0/src/LICENSE) | Parallel programming library | `lens` |
 | **`pretty`** | [`1.1.3.6`](http://hackage.haskell.org/package/pretty-1.1.3.6) | [`BSD-3-Clause`](http://hackage.haskell.org/package/pretty-1.1.3.6/src/LICENSE) | Pretty-printing library | `template-haskell` |
-| `primitive` | [`0.9.1.0`](http://hackage.haskell.org/package/primitive-0.9.1.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/primitive-0.9.1.0/src/LICENSE) | Primitive memory-related operations | `vector` |
 | **`process`** | [`1.6.19.0`](http://hackage.haskell.org/package/process-1.6.19.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/process-1.6.19.0/src/LICENSE) | Process libraries | `ghc` |
-| `reflection` | [`2.1.9`](http://hackage.haskell.org/package/reflection-2.1.9) | [`BSD-3-Clause`](http://hackage.haskell.org/package/reflection-2.1.9/src/LICENSE) | Reifies arbitrary terms into types that can be reflected back into terms | `lens` |
 | **`semaphore-compat`** | [`1.0.0`](http://hackage.haskell.org/package/semaphore-compat-1.0.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/semaphore-compat-1.0.0) | Cross-platform abstraction for system semaphores | `ghc` |
-| `semigroupoids` | [`6.0.2`](http://hackage.haskell.org/package/semigroupoids-6.0.2) | [`BSD-2-Clause`](http://hackage.haskell.org/package/semigroupoids-6.0.2/src/LICENSE) | Semigroupoids: Category sans id | `adjunctions`, `either`, `free`, `kan-extensions`, `lens` |
+| `semigroupoids` | [`6.0.2`](http://hackage.haskell.org/package/semigroupoids-6.0.2) | [`BSD-2-Clause`](http://hackage.haskell.org/package/semigroupoids-6.0.2/src/LICENSE) | Semigroupoids: Category sans id | `adjunctions`, `either`, `free`, `kan-extensions` |
 | **`stm`** | [`2.5.3.1`](http://hackage.haskell.org/package/stm-2.5.3.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/stm-2.5.3.1/src/LICENSE) | Software Transactional Memory | `StateVar`, `exceptions`, `ghc`, `invariant`, `transformers-base` |
-| `tagged` | [`0.8.10`](http://hackage.haskell.org/package/tagged-0.8.10) | [`BSD-3-Clause`](http://hackage.haskell.org/package/tagged-0.8.10/src/LICENSE) | Haskell 98 phantom types to avoid unsafely passing dummy arguments | `adjunctions`, `bifunctors`, `comonad`, `distributive`, `indexed-traversable-instances`, `invariant`, `lens`, `profunctors`, `semigroupoids` |
-| **`text`** | [`2.1.1`](http://hackage.haskell.org/package/text-2.1.1) | [`BSD-2-Clause`](http://hackage.haskell.org/package/text-2.1.1/src/LICENSE) | An efficient packed Unicode text type. | `hashable`, `lens`, `strict` |
-| `these` | [`1.2.1`](http://hackage.haskell.org/package/these-1.2.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/these-1.2.1/src/LICENSE) | An either-or-both data type. | `lens`, `strict` |
+| `tagged` | [`0.8.10`](http://hackage.haskell.org/package/tagged-0.8.10) | [`BSD-3-Clause`](http://hackage.haskell.org/package/tagged-0.8.10/src/LICENSE) | Haskell 98 phantom types to avoid unsafely passing dummy arguments | `adjunctions`, `bifunctors`, `comonad`, `distributive`, `invariant`, `profunctors`, `semigroupoids` |
+| **`text`** | [`2.1.1`](http://hackage.haskell.org/package/text-2.1.1) | [`BSD-2-Clause`](http://hackage.haskell.org/package/text-2.1.1/src/LICENSE) | An efficient packed Unicode text type. | `hashable`, `strict` |
+| `these` | [`1.2.1`](http://hackage.haskell.org/package/these-1.2.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/these-1.2.1/src/LICENSE) | An either-or-both data type. | `strict` |
 | **`time`** | [`1.12.2`](http://hackage.haskell.org/package/time-1.12.2) | [`BSD-2-Clause`](http://hackage.haskell.org/package/time-1.12.2/src/LICENSE) | A time library | `directory`, `ghc`, `hpc`, `unix` |
-| `transformers-base` | [`0.4.6`](http://hackage.haskell.org/package/transformers-base-0.4.6) | [`BSD-3-Clause`](http://hackage.haskell.org/package/transformers-base-0.4.6/src/LICENSE) | Lift computations from the bottom of a transformer stack | `free` |
+| `transformers-base` | [`0.4.6.1`](http://hackage.haskell.org/package/transformers-base-0.4.6.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/transformers-base-0.4.6.1/src/LICENSE) | Lift computations from the bottom of a transformer stack | `free` |
 | `transformers-compat` | [`0.7.2`](http://hackage.haskell.org/package/transformers-compat-0.7.2) | [`BSD-3-Clause`](http://hackage.haskell.org/package/transformers-compat-0.7.2/src/LICENSE) | A small compatibility shim for the transformers library | `semigroupoids`, `transformers-base` |
 | **`unix`** | [`2.8.5.1`](http://hackage.haskell.org/package/unix-2.8.5.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/unix-2.8.5.1/src/LICENSE) | POSIX functionality | `directory`, `ghc`, `ghc-boot`, `ghci`, `process`, `semaphore-compat` |
-| `unordered-containers` | [`0.2.21`](http://hackage.haskell.org/package/unordered-containers-0.2.21) | [`BSD-3-Clause`](http://hackage.haskell.org/package/unordered-containers-0.2.21/src/LICENSE) | Efficient hashing-based container types | `indexed-traversable-instances`, `invariant`, `lens`, `semigroupoids` |
-| `vector` | [`0.13.2.0`](http://hackage.haskell.org/package/vector-0.13.2.0) | [`BSD-3-Clause`](http://hackage.haskell.org/package/vector-0.13.2.0/src/LICENSE) | Efficient Arrays | `indexed-traversable-instances`, `lens` |
-| `vector-stream` | [`0.1.0.1`](http://hackage.haskell.org/package/vector-stream-0.1.0.1) | [`BSD-3-Clause`](http://hackage.haskell.org/package/vector-stream-0.1.0.1/src/LICENSE) | Efficient Streams | `vector` |
+| `unordered-containers` | [`0.2.21`](http://hackage.haskell.org/package/unordered-containers-0.2.21) | [`BSD-3-Clause`](http://hackage.haskell.org/package/unordered-containers-0.2.21/src/LICENSE) | Efficient hashing-based container types | `invariant`, `semigroupoids` |
 
diff --git a/src/Yaya/Applied.hs b/src/Yaya/Applied.hs
--- a/src/Yaya/Applied.hs
+++ b/src/Yaya/Applied.hs
@@ -1,4 +1,8 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
 {-# OPTIONS_GHC -fplugin-opt=NoRecursion:ignore-methods:sconcat #-}
 
 -- __NB__: base-4.17 moves `IsList` to its own module, which avoids the unsafety
@@ -9,10 +13,6 @@
 #else
 {-# LANGUAGE Trustworthy #-}
 #endif
-{-# LANGUAGE TypeApplications #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE ViewPatterns #-}
-{-# OPTIONS_GHC -Wno-orphans #-}
 
 module Yaya.Applied
   ( Void,
@@ -54,35 +54,31 @@
   )
 where
 
-import safe "base" Control.Category (Category (id, (.)))
-import safe "base" Data.Foldable (Foldable (foldr))
+import safe "base" Control.Category (id, (.))
+import safe "base" Data.Foldable (Foldable, foldr)
 import safe "base" Data.Function (flip)
-import safe "base" Data.Functor (Functor (fmap))
-import safe "base" Data.Functor.Identity (Identity (runIdentity))
+import safe "base" Data.Functor (Functor, fmap)
+import safe "base" Data.Functor.Identity (Identity, runIdentity)
 import safe "base" Data.Int (Int)
-import safe "base" Data.Monoid (Monoid (mempty))
-import safe "base" Data.Ord (Ord (max))
+import safe "base" Data.Monoid (Monoid, mempty)
+import safe "base" Data.Ord (Ord, max)
 import safe "base" Data.Semigroup (Semigroup, stimes, stimesMonoid, (<>))
-
--- See comment on @{-# LANGUAGE Safe #-}@ above.
-#if MIN_VERSION_base(4, 17, 0)
-import "base" GHC.IsList (IsList)
-import qualified "base" GHC.IsList as IsList
-#else
-import "base" GHC.Exts (IsList)
-import qualified "base" GHC.Exts as IsList
-#endif
 import safe "base" Numeric.Natural (Natural)
 import safe "free" Control.Monad.Trans.Free (FreeF (Free, Pure))
 import safe "this" Yaya.Fold
   ( Algebra,
-    Corecursive (ana),
+    Corecursive,
     Mu,
     Nu,
-    Projectable (project),
-    Recursive (cata),
-    Steppable (embed),
+    Projectable,
+    Recursive,
+    Steppable,
+    ana,
+    cata,
     cata2,
+    embed,
+    project,
+    pattern Embed,
   )
 import safe "this" Yaya.Fold.Common
   ( diagonal,
@@ -108,6 +104,15 @@
   )
 import safe "base" Prelude (Integral, fromIntegral)
 
+-- See comment on @{-# LANGUAGE Safe #-}@ above.
+#if MIN_VERSION_base(4, 17, 0)
+import "base" GHC.IsList (IsList)
+import qualified "base" GHC.IsList as IsList
+#else
+import "base" GHC.Exts (IsList)
+import qualified "base" GHC.Exts as IsList
+#endif
+
 now :: (Steppable (->) t (Either a)) => a -> t
 now = embed . Left
 
@@ -117,7 +122,8 @@
 runToEnd = cata fromEither
 
 -- | Converts exceptional divergence to non-termination.
-fromMaybe :: (Steppable (->) t (Either a), Corecursive (->) t (Either a)) => Maybe a -> t
+fromMaybe ::
+  (Steppable (->) t (Either a), Corecursive (->) t (Either a)) => Maybe a -> t
 fromMaybe = maybe (ana (toRight . never) ()) now
 
 type Void = Mu Identity
@@ -160,8 +166,13 @@
 instance Monoid (Mu (XNor a)) where
   mempty = embed Neither
 
+-- |
+--
+--  __NB__: This can’t be implemented using `Day`, because we need to know that
+--          the `XNor` contains the fixed-point. And even if we could, it would
+--          require `Steppable` rather than just `Projectable`.
 drop' :: (Projectable (->) t (XNor a)) => Maybe (t -> t) -> t -> t
-drop' (Just fn) (project -> Both _ t) = fn t
+drop' (Just fn) (Embed (Both _ t)) = fn t
 drop' _ t = t
 
 drop :: (Recursive (->) n Maybe, Projectable (->) t (XNor a)) => n -> t -> t
diff --git a/src/Yaya/Experimental/Foldable.hs b/src/Yaya/Experimental/Foldable.hs
--- a/src/Yaya/Experimental/Foldable.hs
+++ b/src/Yaya/Experimental/Foldable.hs
@@ -7,18 +7,19 @@
 --   As these few operations have the usual signatures, the rest of the type
 --   class can be implemented in the as in @base@.
 module Yaya.Experimental.Foldable
-  ( Listable (naturalList),
+  ( Listable,
     foldMap,
     foldl,
     foldr,
+    naturalList,
   )
 where
 
-import "base" Control.Category (Category (id, (.)))
+import "base" Control.Category (id, (.))
 import "base" Data.Function (flip)
 import "base" Data.Monoid (Monoid)
 import "free" Control.Monad.Trans.Free (Free, iter)
-import "this" Yaya.Fold (Recursive (cata))
+import "this" Yaya.Fold (Recursive, cata)
 import "this" Yaya.Fold.Common (lowerMonoid)
 import "this" Yaya.Pattern (XNor (Both, Neither))
 
diff --git a/src/Yaya/Fold.hs b/src/Yaya/Fold.hs
--- a/src/Yaya/Fold.hs
+++ b/src/Yaya/Fold.hs
@@ -1,45 +1,49 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE GADTs #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE ViewPatterns #-}
 {-# OPTIONS_GHC -fplugin-opt=NoRecursion:ignore-decls:steppableReadPrec' #-}
 
 module Yaya.Fold
   ( Algebra,
     AlgebraM,
-    AlgebraPrism,
-    BialgebraIso,
     Coalgebra,
     CoalgebraM,
-    CoalgebraPrism,
-    Corecursive (ana),
+    Corecursive,
     DistributiveLaw,
     ElgotAlgebra,
     ElgotAlgebraM,
     ElgotCoalgebra,
+    pattern Embed,
+    pattern Project,
     GAlgebra,
     GAlgebraM,
     GCoalgebra,
     GCoalgebraM,
-    Mu (Mu),
-    Nu (Nu),
-    Projectable (project),
-    Recursive (cata),
-    Steppable (embed),
+    Mu,
+    Nu,
+    Projectable,
+    Recursive,
+    Steppable,
+    ana,
     attributeAlgebra,
     attributeCoalgebra,
-    birecursiveIso,
+    cata,
     cata2,
     colambek,
     constAna,
     constCata,
     constEmbed,
     constProject,
+    distCofreeT,
     distEnvT,
     distIdentity,
     distTuple,
     elgotAna,
     elgotCata,
     elgotCataM,
+    embed,
     ezygoM,
     gana,
     gcata,
@@ -51,16 +55,17 @@
     lowerCoalgebra,
     lowerCoalgebraM,
     lowerDay,
+    project,
     recursiveCompare,
     recursiveCompare',
     recursiveEq,
     recursiveEq',
-    recursivePrism,
     recursiveShowsPrec,
     recursiveShowsPrec',
     seqEither,
+    seqFreeF,
+    seqFreeT,
     seqIdentity,
-    steppableIso,
     steppableReadPrec,
     steppableReadPrec',
     unFree,
@@ -69,64 +74,54 @@
   )
 where
 
-import "base" Control.Applicative (Applicative (pure), (*>))
-import "base" Control.Category (Category ((.)))
+import "base" Control.Applicative (Applicative, pure, (*>))
+import "base" Control.Category (id, (.))
 import "base" Control.Monad (Monad, join, (<=<), (=<<))
-import "base" Data.Bifunctor (Bifunctor (bimap, first, second))
+import "base" Data.Bifunctor (bimap, second)
 import "base" Data.Bitraversable (bisequence)
 import "base" Data.Bool (Bool)
-import "base" Data.Eq (Eq ((==)))
-import "base" Data.Foldable (Foldable (toList))
-import "base" Data.Function (const, flip, ($))
-import "base" Data.Functor (Functor (fmap), (<$>))
+import "base" Data.Eq (Eq, (==))
+import "base" Data.Foldable (Foldable, toList)
+import "base" Data.Function (flip, ($))
+import "base" Data.Functor (Functor, fmap, (<$>))
 import "base" Data.Functor.Classes
-  ( Eq1 (liftEq),
-    Ord1 (liftCompare),
-    Read1 (liftReadPrec),
+  ( Eq1,
+    Ord1,
+    Read1,
     Show1,
+    liftCompare,
+    liftEq,
+    liftReadPrec,
   )
+import "base" Data.Functor.Const (Const (Const), getConst)
+import "base" Data.Functor.Identity (Identity (Identity), runIdentity)
 import "base" Data.Int (Int)
 import "base" Data.List.NonEmpty (NonEmpty ((:|)))
-import "base" Data.Ord (Ord (compare, (<=)), Ordering)
+import "base" Data.Ord (Ord, Ordering, compare, (<=))
 import "base" Data.String (String)
-import "base" Data.Traversable (sequenceA)
+import "base" Data.Traversable (Traversable, sequenceA, traverse)
 import "base" Data.Void (Void, absurd)
 import "base" GHC.Read (expectP, list)
 import "base" GHC.Show (appPrec1)
 import "base" Numeric.Natural (Natural)
 import "base" Text.Read
-  ( Read (readListPrec, readPrec),
+  ( Read,
     ReadPrec,
     parens,
     prec,
+    readListPrec,
     readListPrecDefault,
+    readPrec,
     step,
   )
 import qualified "base" Text.Read.Lex as Lex
-import "base" Text.Show (Show (showsPrec), ShowS, showParen, showString)
-import "comonad" Control.Comonad (Comonad (duplicate, extend, extract))
-import "comonad" Control.Comonad.Trans.Env
-  ( EnvT (EnvT),
-    ask,
-    lowerEnvT,
-    runEnvT,
-  )
+import "base" Text.Show (Show, ShowS, showParen, showString, showsPrec)
+import "comonad" Control.Comonad (Comonad, duplicate, extend, extract)
+import "comonad" Control.Comonad.Trans.Env (EnvT (EnvT), lowerEnvT, runEnvT)
 import "free" Control.Comonad.Cofree (Cofree ((:<)))
 import "free" Control.Monad.Trans.Free (Free, FreeF (Free, Pure), free, runFree)
 import "kan-extensions" Data.Functor.Day (Day (Day))
-import "lens" Control.Lens
-  ( Const (Const, getConst),
-    Identity (Identity, runIdentity),
-    Iso',
-    Prism',
-    Traversable (traverse),
-    iso,
-    matching,
-    prism,
-    review,
-    view,
-  )
-import "strict" Data.Strict.Classes (Strict (toStrict))
+import "strict" Data.Strict.Classes (toStrict)
 import "this" Yaya.Fold.Common
   ( compareDay,
     diagonal,
@@ -134,7 +129,7 @@
     fromEither,
     showsPrecF,
   )
-import "this" Yaya.Functor (DFunctor (dmap))
+import "this" Yaya.Functor (DFunctor, dmap)
 import "this" Yaya.Pattern
   ( AndMaybe (Indeed, Only),
     Either (Left, Right),
@@ -146,8 +141,16 @@
     snd,
     uncurry,
   )
-import "base" Prelude (Enum (pred, succ))
+import "base" Prelude (pred, succ)
 
+-- NB: Prior to base 4.19, "Data.Functor" doesn’t export `unzip`, but starting
+--     with base 4.22, the one from "Data.List.NonEmpty" is monomorphic.
+#if MIN_VERSION_base(4, 19, 0)
+import "base" Data.Functor (unzip)
+#else
+import "base" Data.List.NonEmpty (unzip)
+#endif
+
 -- $setup
 -- >>> :seti -XTypeApplications
 
@@ -183,6 +186,41 @@
 class Projectable c t f | t -> f where
   project :: Coalgebra c f t
 
+-- | This pattern is useful when you need to match multiple levels of a pattern
+--   functor. It won’t break exhaustiveness checking and, despite being named
+--   `Embed`, only requires `Projectable`.
+--
+-- >>> case 3 :: Natural of {x@(Embed y) -> (x, y)}
+-- (3,Just 2)
+--
+-- >>> case project [1, 2, 3] of {Both x (Embed (Both y z)) -> (x, y, z)}
+-- (1,2,[3])
+pattern Embed :: (Projectable (->) t f) => f t -> t
+pattern Embed ft <- (project -> ft)
+
+-- | This pattern is useful when you need to match the projection of a structure
+--   that has nicer embedded syntax, or if you’re only going to call `embed` on
+--   the extracted values anyway. It won’t break exhaustiveness checking.
+--
+-- >>> case project (3 :: Natural) of {x@(Project y) -> (x, y)}
+-- (Just 2,3)
+--
+-- >>> case project [1, 2, 3] of {x@(Project [1, 2, 3]) -> x}
+-- Both 1 [2,3]
+pattern Project :: (Steppable (->) t f) => t -> f t
+pattern Project t <- (embed -> t)
+
+-- @COMPLETE@ on polymorphic pattern synonyms _requires_ a type constructor for
+-- disambiguation before GHC 9.2. In that case, we define it on the few
+-- constructors we have in scope here.
+#if MIN_VERSION_GLASGOW_HASKELL(9, 2, 0, 0)
+{-# COMPLETE Embed #-}
+{-# COMPLETE Project #-}
+#else
+{-# COMPLETE Embed :: Mu #-}
+{-# COMPLETE Embed :: Nu #-}
+#endif
+
 -- | Structures you can walk through step-by-step.
 class (Projectable c t f) => Steppable c t f | t -> f where
   embed :: Algebra c f t
@@ -260,6 +298,7 @@
   \f p ->
     showParen (appPrec1 <= p) $
       showString embedOperation . showString " " . showsFPrec f appPrec1
+{-# INLINEABLE recursiveShowsPrec' #-}
 
 -- | An implementation of `showsPrec` for any `Recursive` instance.
 #if MIN_VERSION_GLASGOW_HASKELL(8, 8, 0, 0) \
@@ -297,6 +336,7 @@
 --         `steppableReadPrec`, which requires `Steppable` instead.
 recursiveShowsPrec :: (Recursive (->) t f, Show1 f) => Int -> t -> ShowS
 recursiveShowsPrec = recursiveShowsPrec' $ flip showsPrecF
+{-# INLINEABLE recursiveShowsPrec #-}
 
 -- | Like `steppableReadPrec`, but allows you to provide a custom display
 --   function for @f@.
@@ -336,6 +376,7 @@
 
 instance (Functor f) => Projectable (->) (Mu f) f where
   project = lambek
+  {-# INLINEABLE project #-}
 
 instance (Functor f) => Steppable (->) (Mu f) f where
   embed m = Mu (\f -> f (fmap (cata f) m))
@@ -348,6 +389,7 @@
 
 instance (Functor f, Foldable f, Eq1 f) => Eq (Mu f) where
   (==) = recursiveEq
+  {-# INLINEABLE (==) #-}
 
 -- | @since 0.6.1.0
 instance (Functor f, Foldable f, Ord1 f) => Ord (Mu f) where
@@ -367,9 +409,11 @@
 
 instance (Functor f) => Projectable (->) (Nu f) f where
   project (Nu f a) = Nu f <$> f a
+  {-# INLINEABLE project #-}
 
 instance (Functor f) => Steppable (->) (Nu f) f where
   embed = colambek
+  {-# INLINEABLE embed #-}
 
 instance Corecursive (->) (Nu f) f where
   ana = Nu
@@ -581,12 +625,52 @@
 
 distEnvT ::
   (Functor f) =>
-  Algebra (->) f a ->
+  -- |
+  --
+  --  __NB__: To be a true `DistributiveLaw`, this must be an @`Algebra` (->) f
+  --          a@, but this more general version is useful in certain cases (like
+  --         `distCofreeT`).
+  (f a -> b) ->
   DistributiveLaw (->) f w ->
-  DistributiveLaw (->) f (EnvT a w)
-distEnvT φ k =
-  uncurry EnvT . bimap (φ . fmap ask) (k . fmap lowerEnvT) . diagonal
+  f (EnvT a w c) ->
+  EnvT b w (f c)
+distEnvT φ k = uncurry EnvT . bimap φ k . toStrict . unzip . fmap runEnvT
 
+distCofreeT ::
+  ( Corecursive (->) (t (f a)) (EnvT (f a) h),
+    Projectable (->) (t a) (EnvT a h),
+    Functor f
+  ) =>
+  DistributiveLaw (->) f h ->
+  f (t a) ->
+  t (f a)
+distCofreeT k = ana $ distEnvT id k . fmap project
+
+seqFreeF ::
+  (Functor f) =>
+  -- |
+  --
+  --  __NB__: To be a true `DistributiveLaw`, this must be a @`Coalgebra` (->) f
+  --          a@, but this more general version is useful in certain cases (like
+  --         `seqFreeT`).
+  (a -> f b) ->
+  DistributiveLaw (->) m f ->
+  FreeF m a (f c) ->
+  f (FreeF m b c)
+seqFreeF ψ k = \case
+  Pure a -> Pure <$> ψ a
+  Free ft -> Free <$> k ft
+
+seqFreeT ::
+  ( Recursive (->) (t (f a)) (FreeF h (f a)),
+    Steppable (->) (t a) (FreeF h a),
+    Functor f
+  ) =>
+  DistributiveLaw (->) h f ->
+  t (f a) ->
+  f (t a)
+seqFreeT k = cata $ fmap embed . seqFreeF id k
+
 seqEither ::
   (Functor f) => Coalgebra (->) f a -> DistributiveLaw (->) (Either a) f
 seqEither ψ = fromEither . bimap (fmap Left . ψ) (fmap Right)
@@ -660,29 +744,3 @@
 
 instance Corecursive (->) (Maybe a) (Const (Maybe a)) where
   ana = constAna
-
--- * Optics
-
-type BialgebraIso f a = Iso' (f a) a
-
-type AlgebraPrism f a = Prism' (f a) a
-
-type CoalgebraPrism f a = Prism' a (f a)
-
-steppableIso :: (Steppable (->) t f) => BialgebraIso f t
-steppableIso = iso embed project
-
-birecursiveIso ::
-  (Recursive (->) t f, Corecursive (->) t f) =>
-  BialgebraIso f a ->
-  Iso' t a
-birecursiveIso alg = iso (cata (view alg)) (ana (review alg))
-
-recursivePrism ::
-  (Recursive (->) t f, Corecursive (->) t f, Traversable f) =>
-  AlgebraPrism f a ->
-  Prism' t a
-recursivePrism alg =
-  prism
-    (ana (review alg))
-    (\t -> first (const t) $ cata (matching alg <=< sequenceA) t)
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
@@ -31,21 +31,21 @@
   )
 where
 
-import "base" Control.Applicative (Applicative (pure))
-import "base" Control.Category (Category (id, (.)))
+import "base" Control.Applicative (pure)
+import "base" Control.Category (id, (.))
 import "base" Control.Monad (Monad, join)
 import "base" Data.Bool (Bool (False, True), (&&))
-import "base" Data.Eq (Eq ((==)))
-import "base" Data.Foldable (Foldable (foldr, toList), and, fold)
+import "base" Data.Eq ((==))
+import "base" Data.Foldable (Foldable, and, fold, foldr, toList)
 import "base" Data.Function (($), (&))
-import "base" Data.Functor (Functor (fmap), void)
-import "base" Data.Functor.Classes (Eq1 (liftEq), Show1 (liftShowsPrec))
-import "base" Data.Functor.Identity (Identity (Identity, runIdentity))
+import "base" Data.Functor (Functor, fmap, void)
+import "base" Data.Functor.Classes (Eq1, Show1, liftEq, liftShowsPrec)
+import "base" Data.Functor.Identity (Identity (Identity), runIdentity)
 import "base" Data.Int (Int)
 import "base" Data.List (zipWith)
-import "base" Data.Monoid (Monoid (mempty))
-import "base" Data.Ord (Ord (max), Ordering)
-import "base" Data.Semigroup (Semigroup ((<>)))
+import "base" Data.Monoid (Monoid, mempty)
+import "base" Data.Ord (Ordering, max)
+import "base" Data.Semigroup (Semigroup, (<>))
 import "base" GHC.Show (showList__)
 import "base" Numeric.Natural (Natural)
 import "base" Text.Show (ShowS)
@@ -62,7 +62,7 @@
     maybe,
     xnor,
   )
-import "base" Prelude (Integer, Num ((*), (+), (-)))
+import "base" Prelude (Integer, Num, (*), (+), (-))
 
 -- | Converts the free monoid (a list) into some other `Monoid`.
 lowerMonoid :: (Monoid m) => (a -> m) -> XNor a m -> m
@@ -86,6 +86,7 @@
 equalDay eqF (Day f1 f2 fn) =
   eqF (void f1) (void f2)
     && and (zipWith fn (toList f1) (toList f2))
+{-# INLINEABLE equalDay #-}
 
 -- | Provides equality over arbitrary pattern functors.
 equal :: (Functor f, Foldable f, Eq1 f) => Day f f Bool -> Bool
@@ -102,6 +103,7 @@
 compareDay compareF (Day f1 f2 fn) =
   compareF (void f1) (void f2)
     <> fold (zipWith fn (toList f1) (toList f2))
+{-# INLINEABLE compareDay #-}
 
 -- | Provides show over arbitrary pattern functors.
 --
@@ -191,7 +193,7 @@
 
 -- * sequence generators
 
---
+-- $sequence-generators
 --   These functions are defined with different type parameters in order to
 --   constrain the implementation, but to be used as coalgebras, all of the
 --   parameters need to be specialized to the same type.
diff --git a/src/Yaya/Fold/Native.hs b/src/Yaya/Fold/Native.hs
--- a/src/Yaya/Fold/Native.hs
+++ b/src/Yaya/Fold/Native.hs
@@ -6,41 +6,40 @@
 --   manner.
 module Yaya.Fold.Native
   ( module Yaya.Fold.Native.Internal,
-    Fix (Fix, unFix),
-    distCofreeT,
+    Fix,
   )
 where
 
-import "base" Control.Category (Category ((.)))
-import "base" Data.Bifunctor (Bifunctor (bimap))
-import "base" Data.Eq (Eq ((==)))
-import "base" Data.Foldable (Foldable (toList))
+import "base" Control.Category ((.))
+import "base" Data.Eq (Eq, (==))
+import "base" Data.Foldable (Foldable, toList)
 import "base" Data.Function (($))
-import "base" Data.Functor (Functor (fmap))
+import "base" Data.Functor (Functor, fmap)
 import "base" Data.Functor.Classes (Eq1, Ord1, Read1, Show1)
 import "base" Data.List.NonEmpty (NonEmpty ((:|)))
-import "base" Data.Ord (Ord (compare))
+import "base" Data.Ord (Ord, compare)
 import "base" Numeric.Natural (Natural)
-import "base" Text.Read (Read (readListPrec, readPrec), readListPrecDefault)
-import "base" Text.Show (Show (showsPrec))
-import "comonad" Control.Comonad (Comonad (extract))
-import "comonad" Control.Comonad.Trans.Env (EnvT (EnvT), runEnvT)
-import "free" Control.Comonad.Cofree (Cofree ((:<)), unwrap)
+import "base" Text.Read (Read, readListPrec, readListPrecDefault, readPrec)
+import "base" Text.Show (Show, showsPrec)
+import "comonad" Control.Comonad.Trans.Env (EnvT, runEnvT)
+import "free" Control.Comonad.Cofree (Cofree ((:<)))
 import "free" Control.Monad.Trans.Free (Free, FreeF (Free, Pure), free)
-import "strict" Data.Strict.Classes (Strict (toStrict))
+import "strict" Data.Strict.Classes (toStrict)
 import "this" Yaya.Fold
-  ( Corecursive (ana),
-    DistributiveLaw,
-    Projectable (project),
-    Recursive (cata),
-    Steppable (embed),
+  ( Corecursive,
+    Projectable,
+    Recursive,
+    Steppable,
+    ana,
+    cata,
+    embed,
+    project,
     recursiveCompare,
     recursiveEq,
     recursiveShowsPrec,
     steppableReadPrec,
   )
-import "this" Yaya.Fold.Common (diagonal)
-import "this" Yaya.Fold.Native.Internal (Cofix (unCofix))
+import "this" Yaya.Fold.Native.Internal (Cofix)
 import "this" Yaya.Pattern
   ( AndMaybe (Indeed, Only),
     Maybe,
@@ -50,16 +49,17 @@
 
 -- | A fixed-point constructor that uses Haskell's built-in recursion. This is
 --   strict/recursive.
-newtype Fix f = Fix {unFix :: f (Fix f)}
+newtype Fix f = Fix (f (Fix f))
 
 instance Projectable (->) (Fix f) f where
-  project = unFix
+  project (Fix fFix) = fFix
 
 instance Steppable (->) (Fix f) f where
   embed = Fix
 
 instance (Functor f) => Recursive (->) (Fix f) f where
   cata ɸ = ɸ . fmap (cata ɸ) . project
+  {-# INLINEABLE cata #-}
 
 instance (Functor f, Foldable f, Eq1 f) => Eq (Fix f) where
   (==) = recursiveEq
@@ -106,10 +106,3 @@
 
 instance (Functor f) => Corecursive (->) (Cofree f a) (EnvT a f) where
   ana ψ = uncurry (:<) . fmap (fmap (ana ψ)) . toStrict . runEnvT . ψ
-
-distCofreeT ::
-  (Functor f, Functor h) =>
-  DistributiveLaw (->) f h ->
-  DistributiveLaw (->) f (Cofree h)
-distCofreeT k =
-  ana $ uncurry EnvT . bimap (fmap extract) (k . fmap unwrap) . diagonal
diff --git a/src/Yaya/Fold/Native/Internal.hs b/src/Yaya/Fold/Native/Internal.hs
--- a/src/Yaya/Fold/Native/Internal.hs
+++ b/src/Yaya/Fold/Native/Internal.hs
@@ -1,42 +1,46 @@
 {-# LANGUAGE Safe #-}
--- NB: We disable @StrictData@ here in order for `Cofix` to be lazy. I don’t
---     think there is any way to explicitly add @~@ patterns that has the
---     correct semantics.
+-- __NB__: We disable @StrictData@ here in order for `Cofix` to be lazy. I don’t
+--         think there is any way to explicitly add @~@ patterns that has the
+--         correct semantics.
 {-# LANGUAGE NoStrictData #-}
 {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
 
 -- | This module only exists to restrict the scope of @NoStrictData@. Everything
 --    is re-exported via "Yaya.Fold".
 module Yaya.Fold.Native.Internal
-  ( Cofix (Cofix, unCofix),
+  ( Cofix,
   )
 where
 
-import "base" Control.Category (Category ((.)))
-import "base" Data.Functor (Functor (fmap))
+import "base" Control.Category ((.))
+import "base" Data.Functor (Functor, fmap)
 import "base" Data.Functor.Classes (Read1)
-import "base" Text.Read (Read (readListPrec, readPrec), readListPrecDefault)
+import "base" Text.Read (Read, readListPrec, readListPrecDefault, readPrec)
 import "this" Yaya.Fold
-  ( Corecursive (ana),
-    Projectable (project),
-    Steppable (embed),
+  ( Corecursive,
+    Projectable,
+    Steppable,
+    ana,
+    embed,
+    project,
     steppableReadPrec,
   )
 
 -- | A fixed-point constructor that uses Haskell's built-in recursion. This is
 --   lazy/corecursive.
-data Cofix f = Cofix {unCofix :: f (Cofix f)}
+data Cofix f = Cofix (f (Cofix f))
 
 {-# HLINT ignore Cofix "Use newtype instead of data" #-}
 
 instance Projectable (->) (Cofix f) f where
-  project = unCofix
+  project (Cofix fCofix) = fCofix
 
 instance Steppable (->) (Cofix f) f where
   embed = Cofix
 
 instance (Functor f) => Corecursive (->) (Cofix f) f where
   ana φ = embed . fmap (ana φ) . φ
+  {-# INLINEABLE ana #-}
 
 -- | @since 0.6.1.0
 instance (Read1 f) => Read (Cofix f) where
diff --git a/src/Yaya/Functor.hs b/src/Yaya/Functor.hs
--- a/src/Yaya/Functor.hs
+++ b/src/Yaya/Functor.hs
@@ -3,16 +3,18 @@
 -- | This should probably be a separate library, but it provides a number of
 --   functor type classes between various categories.
 module Yaya.Functor
-  ( DFunctor (dmap),
-    HFunctor (hmap),
+  ( DFunctor,
+    HFunctor,
+    dmap,
     firstMap,
+    hmap,
   )
 where
 
-import "base" Control.Category (Category ((.)))
+import "base" Control.Category ((.))
 import "base" Data.Bifunctor (Bifunctor, first)
 import "base" Data.Function (($))
-import "base" Data.Functor (Functor (fmap))
+import "base" Data.Functor (Functor, fmap)
 import "base" Data.Functor.Compose (Compose (Compose))
 import "base" Data.Functor.Product (Product (Pair))
 import "base" Data.Kind (Type)
diff --git a/src/Yaya/Pattern.hs b/src/Yaya/Pattern.hs
--- a/src/Yaya/Pattern.hs
+++ b/src/Yaya/Pattern.hs
@@ -11,44 +11,56 @@
     module Data.Strict.Tuple,
     AndMaybe (Indeed, Only),
     XNor (Both, Neither),
+    isNeither,
     andMaybe,
     xnor,
   )
 where
 
 import "base" Control.Applicative
-  ( Alternative ((<|>)),
-    Applicative (liftA2, pure, (<*>)),
+  ( Applicative,
+    liftA2,
+    pure,
     (*>),
+    (<*>),
+    (<|>),
   )
-import "base" Control.Category (Category ((.)))
-import "base" Control.Monad (Monad ((>>=)))
-import "base" Data.Bifunctor (Bifunctor (bimap))
+import "base" Control.Category ((.))
+import "base" Control.Monad (Monad, (>>=))
+import "base" Data.Bifunctor (Bifunctor, bimap)
 import "base" Data.Bool (Bool (False, True), (&&))
-import "base" Data.Eq (Eq ((==)))
+import "base" Data.Eq (Eq, (==))
 import "base" Data.Foldable (Foldable)
 import "base" Data.Function (($))
 import "base" Data.Functor (Functor, (<$), (<$>))
 import "base" Data.Functor.Classes
-  ( Eq1 (liftEq),
-    Eq2 (liftEq2),
-    Ord1 (liftCompare),
-    Ord2 (liftCompare2),
-    Read1 (liftReadPrec),
-    Read2 (liftReadPrec2),
-    Show1 (liftShowsPrec),
-    Show2 (liftShowsPrec2),
+  ( Eq1,
+    Eq2,
+    Ord1,
+    Ord2,
+    Read1,
+    Read2,
+    Show1,
+    Show2,
+    liftCompare,
+    liftCompare2,
+    liftEq,
+    liftEq2,
+    liftReadPrec,
+    liftReadPrec2,
+    liftShowsPrec,
+    liftShowsPrec2,
   )
-import "base" Data.Ord (Ord (compare, (<=)), Ordering (EQ, GT, LT))
+import "base" Data.Ord (Ord, Ordering (EQ, GT, LT), compare, (<=))
 import "base" Data.Semigroup ((<>))
 import "base" Data.Traversable (Traversable)
 import qualified "base" Data.Tuple as Tuple
 import "base" GHC.Generics (Generic, Generic1)
 import "base" GHC.Read (expectP)
-import "base" Text.Read (Read (readListPrec, readPrec), parens, prec, step)
+import "base" Text.Read (Read, parens, prec, readListPrec, readPrec, step)
 import qualified "base" Text.Read.Lex as Lex
-import "base" Text.Show (Show (showList, showsPrec), showParen, showString)
-import "comonad" Control.Comonad (Comonad (duplicate, extract))
+import "base" Text.Show (Show, showList, showParen, showString, showsPrec)
+import "comonad" Control.Comonad (Comonad, duplicate, extract)
 import "strict" Data.Strict.Either
   ( Either (Left, Right),
     either,
@@ -83,7 +95,7 @@
     zip,
     (:!:),
   )
-import "base" Prelude (Num ((+)))
+import "base" Prelude ((+))
 
 -- | Isomorphic to @'Maybe` (a, b)@, it’s also the pattern functor for lists.
 data XNor a b = Neither | Both ~a b
@@ -108,6 +120,10 @@
   Neither -> neither
   Both x y -> both x y
 
+-- | Eliminator for `XNor`, akin to `Data.Either.isLeft` or `Data.Maybe.isNothing`.
+isNeither :: XNor a b -> Bool
+isNeither = xnor True (\_ _ -> False)
+
 instance (Eq a) => Eq1 (XNor a) where
   liftEq = liftEq2 (==)
 
@@ -136,8 +152,7 @@
   liftReadPrec2 readPrecX _ readPrecY _ =
     let appPrec = 10
      in parens . prec appPrec $
-          Neither
-            <$ expectP (Lex.Ident "Neither")
+          Neither <$ expectP (Lex.Ident "Neither")
             <|> expectP (Lex.Ident "Both")
               *> (Both <$> step readPrecX <*> step readPrecY)
 
@@ -220,8 +235,7 @@
   liftReadPrec2 readPrecX _ readPrecY _ =
     let appPrec = 10
      in parens . prec appPrec $
-          expectP (Lex.Ident "Only")
-            *> (Only <$> step readPrecX)
+          expectP (Lex.Ident "Only") *> (Only <$> step readPrecX)
             <|> expectP (Lex.Ident "Indeed")
               *> (Indeed <$> step readPrecX <*> step readPrecY)
 
diff --git a/src/Yaya/Retrofit.hs b/src/Yaya/Retrofit.hs
--- a/src/Yaya/Retrofit.hs
+++ b/src/Yaya/Retrofit.hs
@@ -29,40 +29,40 @@
 --   disappear.
 module Yaya.Retrofit
   ( module Yaya.Fold,
-    PatternFunctorRules
-      ( PatternFunctorRules,
-        patternCon,
-        patternField,
-        patternType
-      ),
+    PatternFunctorRules (PatternFunctorRules),
     defaultRules,
     extractPatternFunctor,
+    patternCon,
+    patternField,
+    patternType,
+    qualifiedRules,
   )
 where
 
 -- NB: This module does not use the strict library, because its use of `Either`,
 --    `Maybe`, etc. is tied to template-haskell and does not involve recursion
 --     schemes.
-import safe "base" Control.Applicative (Applicative (pure))
-import safe "base" Control.Category (Category (id, (.)))
+import safe "base" Control.Applicative (Applicative, pure)
+import safe "base" Control.Category (id, (.))
 import safe "base" Control.Monad ((<=<))
-import safe "base" Control.Monad.Fail (MonadFail (fail))
-import safe "base" Data.Bifunctor (Bifunctor (bimap))
+import safe "base" Control.Monad.Fail (fail)
+import safe "base" Data.Bifunctor (bimap)
 import safe "base" Data.Bool (Bool, otherwise, (&&))
 import safe "base" Data.Either (Either (Left), either)
-import safe "base" Data.Eq (Eq ((==)))
-import safe "base" Data.Foldable (Foldable (foldl, length, null))
+import safe "base" Data.Eq ((==))
+import safe "base" Data.Foldable (Foldable, foldl, length, null)
 import safe "base" Data.Function (const, flip, ($))
-import safe "base" Data.Functor (Functor (fmap), (<$>))
-import safe "base" Data.Functor.Identity (Identity (Identity, runIdentity))
-import safe "base" Data.List (all, zip, zip3)
+import safe "base" Data.Functor (Functor, fmap, (<$>))
+import safe "base" Data.Functor.Identity (Identity (Identity), runIdentity)
+import safe "base" Data.List (all, elemIndex, splitAt, zip, zip3)
 import safe "base" Data.List.NonEmpty (NonEmpty)
 import safe "base" Data.Maybe (Maybe (Just, Nothing), maybe)
-import safe "base" Data.Semigroup (Semigroup ((<>)))
+import safe "base" Data.Semigroup ((<>))
 import safe "base" Data.String (String)
-import safe "base" Data.Traversable (Traversable (traverse))
+import safe "base" Data.Traversable (Traversable, traverse)
+import safe "base" Data.Tuple (snd)
 import safe "base" Text.Read.Lex (isSymbolChar)
-import safe "base" Text.Show (Show (show))
+import safe "base" Text.Show (Show, show)
 import safe "either" Data.Either.Validation
   ( Validation (Failure, Success),
     validationToEither,
@@ -70,10 +70,14 @@
 import safe qualified "template-haskell" Language.Haskell.TH as TH
 import safe qualified "th-abstraction" Language.Haskell.TH.Datatype as TH.Abs
 import safe "this" Yaya.Fold
-  ( Corecursive (ana),
-    Projectable (project),
-    Recursive (cata),
-    Steppable (embed),
+  ( Corecursive,
+    Projectable,
+    Recursive,
+    Steppable,
+    ana,
+    cata,
+    embed,
+    project,
     recursiveCompare,
     recursiveCompare',
     recursiveEq,
@@ -102,7 +106,8 @@
 conP' = TH.ConP
 #endif
 
--- | Extract a pattern functor and relevant instances from a simply recursive type.
+-- | Extract a pattern functor and relevant instances from a simply recursive
+--   type.
 --
 -- /e.g./
 --
@@ -147,9 +152,12 @@
 -- - `extractPatternFunctor` 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>.
--- - we always generate both `Recursive` and `Corecursive` instances, but one of these is always unsafe.
---   In future, we should check the strictness of the recursive parameter and generate only the appropriate one (unless overridden by a rule).
+--   <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#deriving-functor-instances
+--   GHC's DeriveFunctor>.
+-- - we always generate both `Recursive` and `Corecursive` instances, but one of
+--   these is always unsafe. In future, we should check the strictness of the
+--   recursive parameter and generate only the appropriate one (unless
+--   overridden by a rule).
 extractPatternFunctor :: PatternFunctorRules -> TH.Name -> TH.Q [TH.Dec]
 extractPatternFunctor rules =
   either (fail . displayUnsupportedDatatype) id . makePrimForDI rules
@@ -162,7 +170,8 @@
     patternField :: TH.Name -> TH.Name
   }
 
--- | Default 'PatternFunctorRules': append @F@ or @$@ to data type, constructors and field names.
+-- | Default 'PatternFunctorRules': append @F@ or @$@ to data type, constructors
+--   and field names.
 defaultRules :: PatternFunctorRules
 defaultRules =
   PatternFunctorRules
@@ -171,6 +180,22 @@
       patternField = toFName
     }
 
+-- | Use these rules when you are defining the pattern functor in a different
+--   module from the directly-recursive type, and the directly-recursive type is
+--   imported qualified (so the functor can use the same names for everything).
+qualifiedRules :: PatternFunctorRules
+qualifiedRules =
+  PatternFunctorRules
+    { patternType = stripQualifiers,
+      patternCon = stripQualifiers,
+      patternField = stripQualifiers
+    }
+
+stripQualifiers :: TH.Name -> TH.Name
+stripQualifiers = TH.mkName . f . TH.nameBase
+  where
+    f name = maybe name (snd . flip splitAt name) $ elemIndex '.' name
+
 toFName :: TH.Name -> TH.Name
 toFName = TH.mkName . f . TH.nameBase
   where
@@ -349,7 +374,8 @@
 -------------------------------------------------------------------------------
 
 conNameTraversal :: Traversal' TH.Abs.ConstructorInfo TH.Name
-conNameTraversal = lens TH.Abs.constructorName (\s v -> s {TH.Abs.constructorName = v})
+conNameTraversal =
+  lens TH.Abs.constructorName (\s v -> s {TH.Abs.constructorName = v})
 
 conFieldNameTraversal :: Traversal' TH.Abs.ConstructorInfo TH.Name
 conFieldNameTraversal =
diff --git a/src/Yaya/Zoo.hs b/src/Yaya/Zoo.hs
--- a/src/Yaya/Zoo.hs
+++ b/src/Yaya/Zoo.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE QuantifiedConstraints #-}
 {-# LANGUAGE Safe #-}
 
 -- | Contains all the commonly-named folds that aren’t core to the library. In
@@ -9,7 +10,7 @@
     List,
     Nat,
     NonEmptyList,
-    Partial (Partial, fromPartial),
+    Partial (Partial),
     Stream,
     apo,
     cataM,
@@ -17,6 +18,8 @@
     comap,
     comutu,
     contramap,
+    fromPartial,
+    futu,
     gapo,
     gmutu,
     histo,
@@ -31,40 +34,45 @@
   )
 where
 
-import "base" Control.Applicative (Applicative (pure, (<*>)))
-import "base" Control.Category (Category (id, (.)))
-import "base" Control.Monad (Monad ((>>=)), (<=<))
-import "base" Data.Bifunctor (Bifunctor (bimap, first))
-import "base" Data.Bitraversable (Bitraversable (bitraverse), bisequence)
+import "base" Control.Applicative (Applicative, pure, (<*>))
+import "base" Control.Category (id, (.))
+import "base" Control.Monad (Monad, (<=<), (>>=))
+import "base" Data.Bifunctor (Bifunctor, bimap, first)
+import "base" Data.Bitraversable (Bitraversable, bisequence, bitraverse)
 import "base" Data.Function (flip, ($))
-import "base" Data.Functor (Functor (fmap))
-import "base" Data.Traversable (Traversable (sequenceA))
-import "comonad" Control.Comonad (Comonad (duplicate, extract))
+import "base" Data.Functor (Functor, fmap)
+import "base" Data.Traversable (Traversable, sequenceA)
+import "comonad" Control.Comonad (Comonad, duplicate, extract)
 import "comonad" Control.Comonad.Env (EnvT (EnvT))
-import "free" Control.Comonad.Cofree (Cofree)
-import "profunctors" Data.Profunctor (Profunctor (lmap))
+import "free" Control.Monad.Trans.Free (FreeF)
+import "profunctors" Data.Profunctor (Profunctor, lmap)
 import "this" Yaya.Fold
   ( Algebra,
     AlgebraM,
     Coalgebra,
-    Corecursive (ana),
+    Corecursive,
     DistributiveLaw,
     GAlgebra,
     GAlgebraM,
     GCoalgebra,
     Mu,
     Nu,
-    Projectable (project),
-    Recursive (cata),
-    Steppable (embed),
+    Projectable,
+    Recursive,
+    Steppable,
+    ana,
+    cata,
+    distCofreeT,
     distTuple,
     elgotAna,
+    embed,
     gana,
     gcata,
+    project,
     seqEither,
+    seqFreeT,
   )
 import "this" Yaya.Fold.Common (diagonal, fromEither)
-import "this" Yaya.Fold.Native (distCofreeT)
 import "this" Yaya.Pattern
   ( AndMaybe,
     Either (Left, Right),
@@ -178,8 +186,28 @@
   m a
 mutuM φ' φ = fmap snd . cataM (bisequence . bimap (φ' . fmap swap) φ . diagonal)
 
+futu ::
+  ( Corecursive (->) t f,
+    Functor f,
+    forall x. Recursive (->) (freef x) (FreeF f x),
+    forall x. Steppable (->) (freef x) (FreeF f x),
+    Monad freef
+  ) =>
+  GCoalgebra (->) freef f a ->
+  a ->
+  t
+futu = gana (seqFreeT id)
+
 histo ::
-  (Recursive (->) t f, Functor f) => GAlgebra (->) (Cofree f) f a -> t -> a
+  ( Recursive (->) t f,
+    forall x. Corecursive (->) (cofreef x) (EnvT x f),
+    forall x. Projectable (->) (cofreef x) (EnvT x f),
+    Comonad cofreef,
+    Functor f
+  ) =>
+  GAlgebra (->) cofreef f a ->
+  t ->
+  a
 histo = gcata $ distCofreeT id
 
 -- | A recursion scheme that gives you access to the original structure as you
@@ -258,7 +286,11 @@
 -- | A more general implementation of `fmap`, because it can also work to, from,
 --   or within monomorphic structures, obviating the need for classes like
 --  `Data.MonoTraversable.MonoFunctor`.
-map :: (Recursive (->) t (f a), Steppable (->) u (f b), Bifunctor f) => (a -> b) -> t -> u
+map ::
+  (Recursive (->) t (f a), Steppable (->) u (f b), Bifunctor f) =>
+  (a -> b) ->
+  t ->
+  u
 map f = cata (embed . first f)
 
 -- | A version of `Yaya.Zoo.map` that applies to Corecursive structures.
diff --git a/yaya.cabal b/yaya.cabal
--- a/yaya.cabal
+++ b/yaya.cabal
@@ -3,7 +3,7 @@
 --   exception.
 
 name: yaya
-version: 0.7.0.0
+version: 1.0.0.0
 synopsis: Total recursion schemes.
 description: Recursion schemes allow you to separate recursion from your
              business logic – making your own operations simpler, more modular,
@@ -53,7 +53,7 @@
   location: https://github.com/sellout/yaya.git
   subdir: core
   -- NB: This is the repo version, which is distinct from the package version.
-  tag: v4.0.0
+  tag: v5.0.0
 
 custom-setup
   setup-depends:
@@ -147,8 +147,6 @@
     base ^>= {4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0, 4.20.0, 4.21.0, 4.22.0},
   ghc-options:
     -Weverything
-    -- This one just reports unfixable things, AFAICT.
-    -Wno-all-missed-specialisations
     -- Type inference good.
     -Wno-missing-local-signatures
     -- Warns even when `Unsafe` is explicit, not inferred. See
@@ -174,6 +172,12 @@
       -Wno-missing-poly-kind-signatures
       -- Inference good.
       -Wno-missing-role-annotations
+  -- remove if the oldest supported version is GHC 9.14.1+
+  if impl(ghc >= 9.14.1)
+    ghc-options:
+      -- See
+      -- https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0581-namespace-specified-imports.rst#deprecate-use-of-pattern-in-import-export-lists
+      -Wno-pattern-namespace-specifier
   default-extensions:
     BlockArguments
     DefaultSignatures
@@ -214,7 +218,6 @@
     either ^>= 5,
     free ^>= {5.1.5, 5.2},
     kan-extensions ^>= 5.2,
-    lens ^>= {5, 5.1, 5.2, 5.3},
     profunctors ^>= {5.5.2, 5.6},
     strict ^>= {0.4, 0.5},
     template-haskell ^>= {2.15.0, 2.16.0, 2.17.0, 2.18.0, 2.19.0, 2.20.0, 2.21.0, 2.22.0, 2.23.0, 2.24.0},
