diff --git a/LICENCE b/LICENCE
--- a/LICENCE
+++ b/LICENCE
@@ -1,77 +1,28 @@
-CSIRO Open Source Software License Agreement (variation of the BSD / MIT
-License)
-
-Copyright (c) 2016, Commonwealth Scientific and Industrial Research Organisation
-(CSIRO) ABN 41 687 119 230.
-
-All rights reserved. CSIRO is willing to grant you a license to this
-software on the following terms, except where otherwise indicated for
-third party material.
-
-Redistribution and use of this software in source and binary forms, with or
-without modification, are permitted provided that the following conditions are
-met:
-
-* Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice, this
-  list of conditions and the following disclaimer in the documentation and/or
-  other materials provided with the distribution.
-
-* Neither the name of CSIRO nor the names of its contributors may be used to
-  endorse or promote products derived from this software without specific prior
-  written permission of CSIRO.
-
-EXCEPT AS EXPRESSLY STATED IN THIS AGREEMENT AND TO THE FULL EXTENT PERMITTED BY
-APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS". CSIRO MAKES NO
-REPRESENTATIONS, WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
-REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, THE ABSENCE
-OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
-DISCOVERABLE.
-
-TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL CSIRO BE
-LIABLE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION FOR
-BREACH OF CONTRACT, NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR
-OTHER LIABILITY HOWSOEVER INCURRED.  WITHOUT LIMITING THE SCOPE OF THE PREVIOUS
-SENTENCE THE EXCLUSION OF LIABILITY SHALL INCLUDE: LOSS OF PRODUCTION OR
-OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS OF
-ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR OTHER ECONOMIC
-LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY
-DAMAGES, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, ACCESS OF THE
-SOFTWARE OR ANY OTHER DEALINGS WITH THE SOFTWARE, EVEN IF CSIRO HAS BEEN ADVISED
-OF THE POSSIBILITY OF SUCH CLAIM, LOSS, DAMAGES OR OTHER LIABILITY.
-
-APPLICABLE LEGISLATION SUCH AS THE AUSTRALIAN CONSUMER LAW MAY APPLY
-REPRESENTATIONS, WARRANTIES, OR CONDITIONS, OR IMPOSES OBLIGATIONS OR LIABILITY
-ON CSIRO THAT CANNOT BE EXCLUDED, RESTRICTED OR MODIFIED TO THE FULL EXTENT SET
-OUT IN THE EXPRESS TERMS OF THIS CLAUSE ABOVE "CONSUMER GUARANTEES".  TO THE
-EXTENT THAT SUCH CONSUMER GUARANTEES CONTINUE TO APPLY, THEN TO THE FULL EXTENT
-PERMITTED BY THE APPLICABLE LEGISLATION, THE LIABILITY OF CSIRO UNDER THE
-RELEVANT CONSUMER GUARANTEE IS LIMITED (WHERE PERMITTED AT CSIRO'S OPTION) TO
-ONE OF FOLLOWING REMEDIES OR SUBSTANTIALLY EQUIVALENT REMEDIES:
-
-(a)               THE REPLACEMENT OF THE SOFTWARE, THE SUPPLY OF EQUIVALENT
-                  SOFTWARE, OR SUPPLYING RELEVANT SERVICES AGAIN;
-(b)               THE REPAIR OF THE SOFTWARE;
-(c)               THE PAYMENT OF THE COST OF REPLACING THE
-                  SOFTWARE, OF ACQUIRING EQUIVALENT SOFTWARE, HAVING THE
-                  RELEVANT SERVICES SUPPLIED AGAIN, OR HAVING THE SOFTWARE
-                  REPAIRED.
+Copyright (c) 2016-2017 Commonwealth Scientific and Industrial Research
+Organisation (CSIRO) ABN 41 687 119 230
+Copyright (c) 2017-2026 Tony Morris
 
-IN THIS CLAUSE, CSIRO INCLUDES ANY THIRD PARTY AUTHOR OR OWNER OF ANY PART OF
-THE SOFTWARE OR MATERIAL DISTRIBUTED WITH IT.  CSIRO MAY ENFORCE ANY RIGHTS ON
-BEHALF OF THE RELEVANT THIRD PARTY.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
 
-Third Party Components
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
 
-The following third party components are distributed with the Software.  You
-agree to comply with the license terms for these components as part of accessing
-the Software.  Other third party software may also be identified in separate
-files distributed with the Software.
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
 
-___________________________________________________________________
+3. Neither the name of the copyright holder nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
 
-___________________________________________________________________
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,2 +1,3 @@
+{-# OPTIONS_GHC -Wall -Werror #-}
 import Distribution.Simple
 main = defaultMain
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,23 @@
+0.5.0
+
+* Remove `lens-indexed-plated` dependency to resolve GHC 9.12+ compatibility
+* Add GHC 9.12.4 support
+* Fix GHC 9.8+ compatibility by hiding `uncons`/`unsnoc` from `Papa.Base`
+* Update CI to use `cabal build all` for multi-package project support
+* Add `one >= 0.0.4` constraint for GHC 9.6+ MkSolo support
+* Remove GHC 9.4.8 support (requires older dependency versions)
+
+0.4.0
+
+* Comprehensive type class coverage across ecosystem packages
+* Full lens integration with indexed operations
+* Safe alternatives to partial functions
+* Performance optimizations with INLINE pragmas
+
+0.3.1
+
+* Remove doctests test target and setup
+
 0.2.0
 
 * Reorganisation of all `papa` packages.
diff --git a/papa.cabal b/papa.cabal
--- a/papa.cabal
+++ b/papa.cabal
@@ -1,54 +1,151 @@
+cabal-version:      2.4
 name:               papa
-version:            0.3.1
-license:            BSD3
+version:            0.5.0
+license:            BSD-3-Clause
 license-file:       LICENCE
-author:             Queensland Functional Programming Lab <oᴉ˙ldɟb@llǝʞsɐɥ>
-maintainer:         Queensland Functional Programming Lab <oᴉ˙ldɟb@llǝʞsɐɥ>
-copyright:          Copyright (c) 2016, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230.
-synopsis:           Reasonable default import
+author:             Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ> <dibblego>
+maintainer:         Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ> <dibblego>
+copyright:          Copyright (c) 2016-2017 Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230
+                    Copyright (c) 2017-2026 Tony Morris
+synopsis:           Type class-driven prelude with lens, comonads, and safe alternatives
 category:           Prelude
 description:
-  <<http://i.imgur.com/uZnp9ke.png>>
+  <<https://logo.systemf.com.au/systemf-450x450.png>>
   .
-  Reasonable default import
-homepage:           https://github.com/qfpl/papa
-bug-reports:        https://github.com/qfpl/papa/issues
-cabal-version:      >= 1.10
+  Papa is a curated Haskell prelude that re-exports only total, safe functions and integrates
+  seamlessly with the modern Haskell ecosystem. It eliminates partial functions while providing
+  comprehensive type class coverage across base, lens, bifunctors, semigroupoids, comonads,
+  profunctors, and more.
+  .
+  = Core Design Principles
+  .
+  * __No Partial Functions__ — All re-exported functions are total and safe
+  * __Type Class-Driven__ — Maximizes use of standard type classes for polymorphic code
+  * __Optics Integration__ — Full lens support with indexed operations and plated recursion
+  * __Modern Ecosystem__ — Integrates adjunctions, comonads, profunctors, selective functors, and more
+  .
+  = What's Included
+  .
+  Papa provides a comprehensive set of type classes and operations:
+  .
+  * __Base functionality__ — Safe alternatives to Prelude with Eq1/Eq2, Ord1/Ord2, Show1/Show2
+  * __Functor hierarchy__ — Functor, Applicative, Monad, Alternative, MonadPlus, with Apply/Bind
+  * __Foldable/Traversable__ — Including Foldable1/Traversable1 for non-empty structures
+  * __Lens integration__ — Full optics support with At, Ixed, Plated, IndexedPlated, Field1-9
+  * __Bifunctors__ — Bifunctor, Bifoldable, Bitraversable with indexed variants
+  * __Comonads__ — Comonad, ComonadApply, Env, Store, Traced comonads
+  * __Profunctors__ — Strong, Choice, Closed profunctors (import qualified)
+  * __Containers__ — Map, Set, IntMap, IntSet, Seq, Tree (import qualified)
+  * __Free structures__ — Free monads and Cofree comonads
+  * __Transformers__ — MonadTrans, MonadIO, mtl classes (MonadReader, State, Writer, etc.)
+  * __Specialized functors__ — Contravariant, Distributive, Selective, Witherable
+  * __Generic programming__ — Generic, Generic1, Data, Typeable
+  * __Performance__ — NFData for strict evaluation, all utility functions marked INLINE
+  .
+  = Forbidden Functions
+  .
+  Papa explicitly does NOT export these partial functions:
+  .
+  * @head@, @tail@, @init@, @last@ — Use optics or pattern matching
+  * @(!!)@ — Use safe @(^? ix n)@ from lens (Papa provides a safe version)
+  * @maximum@, @minimum@ — Use @maximum1@/@minimum1@ for non-empty structures
+  * @foldl1@, @foldr1@ — Use Foldable1 versions
+  * @fromJust@ — Use @fromMaybe@ or pattern matching
+  * @read@ — Use @readMaybe@ or parser libraries
+  * @error@, @undefined@ — Use typed errors with Either
+  * All @unsafe*@ functions
+  .
+  = Usage
+  .
+  > {-# LANGUAGE NoImplicitPrelude #-}
+  > import Papa
+  >
+  > -- Use safe, total functions
+  > safeHead :: [a] -> Maybe a
+  > safeHead = (^? ix 0)
+  >
+  > -- Leverage type classes
+  > genericLength :: (Foldable f, Num n) => f a -> n
+  > genericLength = foldl' (\n _ -> n + 1) 0
+  >
+  > -- Work with lenses
+  > data Person = Person { _name :: String, _age :: Int }
+  > name :: Lens' Person String
+  .
+  Some modules require qualified import to avoid name conflicts:
+  .
+  > import qualified Papa.Containers.Data.Map as Map
+  > import qualified Papa.Profunctors.Data.Profunctor as Profunctor
+  .
+  = Future Plans
+  .
+  __Note:__ Future versions may split this package into separate dependencies to reduce
+  compilation times and allow finer-grained control over transitive dependencies. The
+  current monolithic structure prioritizes ease of use and comprehensive type class
+  coverage, but may be reorganized as:
+  .
+  * @papa-base@ — Core prelude with base, bifunctors, semigroupoids
+  * @papa-lens@ — Lens integration and optics
+  * @papa-comonad@ — Comonad hierarchy
+  * @papa-transformers@ — MTL and transformer classes
+  * @papa-ecosystem@ — Profunctors, selective, witherable, etc.
+  .
+  This reorganization would allow users to depend only on the pieces they need while
+  maintaining API compatibility through the top-level @papa@ package as a convenience
+  re-export.
+homepage:           https://gitlab.com/system-f/code/papa
+bug-reports:        https://gitlab.com/system-f/code/papa/issues
 build-type:         Simple
-extra-source-files: changelog.md
+extra-doc-files:    changelog.md
+tested-with:        GHC == 9.6.7
+                  , GHC == 9.8.4
+                  , GHC == 9.10.1
+                  , GHC == 9.12.4
+                  -- GHC 9.0-9.4 require older versions of dependencies:
+                  -- one < 0.0.4, associative < 0.0.4, id < 0.0.3
+                  -- (liftA2 and MkSolo compatibility issues)
 
+flag dev
+  description:      Enable development warnings (-Werror)
+  manual:           True
+  default:          False
+
 source-repository   head
   type:             git
-  location:         git@github.com:qfpl/papa.git
-
-flag                small_base
-  description:      Choose the new, split-up base package.
+  location:         git@gitlab.com:system-f/code/papa.git
 
 library
   default-language:
                     Haskell2010
 
   build-depends:
-                    base >= 4.8 && < 5
-                    , papa-base >= 0.3.1 && < 1
-                    , papa-base-export >= 0.3.1 && < 1
-                    , papa-base-implement >= 0.3.1 && < 1
-                    , papa-bifunctors >= 0.3.1 && < 1
-                    , papa-bifunctors-export >= 0.3.1 && < 1
-                    , papa-bifunctors-implement >= 0.3.1 && < 1
-                    , papa-lens >= 0.3.1 && < 1
-                    , papa-lens-export >= 0.3.1 && < 1
-                    , papa-lens-implement >= 0.3.1 && < 1
-                    , papa-semigroupoids >= 0.3.1 && < 1
-                    , papa-semigroupoids-export >= 0.3.1 && < 1
-                    , papa-semigroupoids-implement >= 0.3.1 && < 1
-                    , papa-x >= 0.3.1 && < 1
-                    , papa-x-export >= 0.3.1 && < 1
-                    , papa-x-implement >= 0.3.1 && < 1
-                    
+                    base >= 4.11 && < 6
+                    , adjunctions >= 4 && < 5
+                    , associative >= 0 && < 1
+                    , bifunctors >= 5 && < 7
+                    , comonad >= 5 && < 6
+                    , containers >= 0.5 && < 1
+                    , contravariant >= 1 && < 2
+                    , deepseq >= 1.4 && < 2
+                    , distributive >= 0 && < 1
+                    , free >= 5 && < 6
+                    , id >= 0 && < 1
+                    , lens >= 4 && < 6
+                    , mtl >= 2 && < 3
+                    , one >= 0.0.4 && < 1
+                    , polytree >= 0 && < 1
+                    , profunctors >= 5 && < 6
+                    , selective >= 0 && < 1
+                    , semigroupoids >= 5 && < 7
+                    , transformers >= 0.5 && < 1
+                    , witherable >= 0 && < 1
+
   ghc-options:
                     -Wall
 
+  if flag(dev)
+    ghc-options:    -Werror
+
   default-extensions:
                     NoImplicitPrelude
 
@@ -57,3 +154,146 @@
 
   exposed-modules:
                     Papa
+                    Papa.Adjunctions
+                    Papa.Adjunctions.Data.Functor.Adjunction
+                    Papa.Adjunctions.Data.Functor.Rep
+                    Papa.Adjunctions.Renamed
+                    Papa.Associative
+                    Papa.Associative.Data.Associative
+                    Papa.Associative.Renamed
+                    Papa.Base
+                    Papa.Base.Control.Applicative
+                    Papa.Base.Control.Arrow
+                    Papa.Base.Control.Category
+                    Papa.Base.Control.DeepSeq
+                    Papa.Base.Control.Monad
+                    Papa.Base.Control.Monad.Cont
+                    Papa.Base.Control.Monad.Error
+                    Papa.Base.Control.Monad.Reader
+                    Papa.Base.Control.Monad.RWS
+                    Papa.Base.Control.Monad.State
+                    Papa.Base.Control.Monad.Trans
+                    Papa.Base.Control.Monad.Writer
+                    Papa.Base.Data.Bool
+                    Papa.Base.Data.Char
+                    Papa.Base.Data.Data
+                    Papa.Base.Data.Either
+                    Papa.Base.Data.Eq
+                    Papa.Base.Data.Foldable
+                    Papa.Base.Data.Function
+                    Papa.Base.Data.Functor
+                    Papa.Base.Data.Int
+                    Papa.Base.Data.List
+                    Papa.Base.Data.List.NonEmpty
+                    Papa.Base.Data.Maybe
+                    Papa.Base.Data.Monoid
+                    Papa.Base.Data.Ord
+                    Papa.Base.Data.Ratio
+                    Papa.Base.Data.Semigroup
+                    Papa.Base.Data.Show
+                    Papa.Base.Data.String
+                    Papa.Base.Data.Traversable
+                    Papa.Base.Data.Void
+                    Papa.Base.GHC.Generics
+                    Papa.Base.Prelude
+                    Papa.Bifunctors
+                    Papa.Bifunctors.Data.Bifoldable
+                    Papa.Comonad
+                    Papa.Comonad.Control.Comonad
+                    Papa.Comonad.Control.Comonad.Env
+                    Papa.Comonad.Control.Comonad.Store
+                    Papa.Comonad.Control.Comonad.Traced
+                    Papa.Comonad.Renamed
+                    Papa.Containers
+                    Papa.Contravariant
+                    Papa.Contravariant.Data.Functor.Contravariant
+                    Papa.Containers.Data.IntMap
+                    Papa.Containers.Data.IntSet
+                    Papa.Containers.Data.Map
+                    Papa.Containers.Data.Seq
+                    Papa.Containers.Data.Set
+                    Papa.Containers.Data.Tree
+                    Papa.Distributive
+                    Papa.Distributive.Data.Distributive
+                    Papa.Free
+                    Papa.Free.Control.Applicative.Free
+                    Papa.Free.Control.Comonad.Cofree
+                    Papa.Free.Control.Monad.Free
+                    Papa.Id
+                    Papa.Id.Data.BiId
+                    Papa.Id.Data.Id
+                    Papa.Lens
+                    Papa.Lens.Data.List
+                    Papa.Lens.Data.Tuple
+                    Papa.One
+                    Papa.One.Control.One
+                    Papa.One.Renamed
+                    Papa.Polytree
+                    Papa.Polytree.Data.Polytree
+                    Papa.Polytree.Renamed
+                    Papa.Profunctors
+                    Papa.Profunctors.Data.Profunctor
+                    Papa.Profunctors.Data.Profunctor.Choice
+                    Papa.Profunctors.Data.Profunctor.Strong
+                    Papa.Profunctors.Renamed
+                    Papa.Selective
+                    Papa.Selective.Control.Selective
+                    Papa.Selective.Renamed
+                    Papa.Semigroupoids
+                    Papa.Semigroupoids.Data.Functor.Bind
+                    Papa.Semigroupoids.Data.Semigroup.Foldable
+                    Papa.Witherable
+                    Papa.Witherable.Renamed
+                    Papa.Witherable.Witherable
+
+test-suite papa-test
+  type:
+                    exitcode-stdio-1.0
+
+  default-language:
+                    Haskell2010
+
+  hs-source-dirs:
+                    test
+
+  main-is:
+                    Main.hs
+
+  build-depends:
+                    base >= 4.11 && < 6
+                    , papa
+
+  ghc-options:
+                    -Wall
+
+  if flag(dev)
+    ghc-options:    -Werror
+
+  default-extensions:
+                    NoImplicitPrelude
+
+test-suite doctest
+  type:
+                    exitcode-stdio-1.0
+
+  hs-source-dirs:
+                    test
+
+  main-is:
+                    Doctest.hs
+
+  build-depends:
+                    base >= 4.11 && < 6
+                    , process >= 1 && < 2
+
+  build-tool-depends:
+                    doctest:doctest >= 0.22 && < 1
+
+  default-language:
+                    Haskell2010
+
+  ghc-options:
+                    -Wall
+
+  if flag(dev)
+    ghc-options:    -Werror
diff --git a/src/Papa.hs b/src/Papa.hs
--- a/src/Papa.hs
+++ b/src/Papa.hs
@@ -1,13 +1,95 @@
 {-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
 
-module Papa(
+-- | Papa prelude - a curated Haskell prelude
+--
+-- This module re-exports the core prelude functionality. Many ecosystem packages
+-- are not re-exported from this module to avoid name conflicts. Users should import
+-- them qualified or directly as needed:
+--
+-- Containers:
+-- > import qualified Papa.Containers.Data.Map as Map
+-- > import qualified Papa.Containers.Data.Set as Set
+--
+-- Free structures:
+-- > import qualified Papa.Free.Control.Monad.Free as Free
+-- > import qualified Papa.Free.Control.Comonad.Cofree as Cofree
+--
+-- Other ecosystem packages (import qualified to avoid conflicts):
+-- > import qualified Papa.Profunctors.Data.Profunctor as Profunctor
+-- > import qualified Papa.Selective.Control.Selective as Selective
+-- > import qualified Papa.Witherable.Witherable as Witherable
+-- > import qualified Papa.Associative.Data.Associative as Associative
+-- > import qualified Papa.One.Control.One as One
+-- > import qualified Papa.Adjunctions.Data.Functor.Rep as Rep
+-- > import qualified Papa.Comonad.Control.Comonad.Traced as Traced
+-- > import qualified Papa.Id.Data.Id as Id
+-- > import qualified Papa.Id.Data.BiId as BiId
+-- > import qualified Papa.Polytree.Data.Polytree as Polytree
+--
+-- | Papa prelude — a comprehensive, type class-driven Haskell prelude
+--
+-- This module re-exports the core functionality. For additional modules,
+-- import them directly:
+--
+-- == Aggregator Modules (import individually)
+--
+-- These modules aggregate related functionality and can be imported separately:
+--
+-- > import Papa.Comonad           -- All comonad functionality
+-- > import Papa.Contravariant      -- Contravariant functors
+-- > import Papa.Distributive       -- Distributive functors
+-- > import Papa.Adjunctions        -- Adjunctions and representable functors
+-- > import Papa.Associative        -- Associative operations
+-- > import Papa.One                -- One type class
+-- > import Papa.Polytree           -- Polytree data structure
+-- > import Papa.Profunctors        -- Profunctor hierarchy
+-- > import Papa.Selective          -- Selective functors
+-- > import Papa.Witherable         -- Witherable and Filterable
+--
+-- == Renamed Modules (conflicts hidden)
+--
+-- For modules with naming conflicts, use the .Renamed versions:
+--
+-- > import Papa.Comonad.Renamed       -- Hides First/Last/Alt/mconcat conflicts
+-- > import Papa.Adjunctions.Renamed   -- Hides 'index' conflict
+-- > import Papa.Associative.Renamed   -- Hides 'null'/'op' conflicts
+-- > import Papa.One.Renamed           -- Hides 'nonEmpty' conflict
+-- > import Papa.Polytree.Renamed      -- Hides 'levels' conflict
+-- > import Papa.Profunctors.Renamed   -- Hides 'WrappedArrow' conflict
+-- > import Papa.Selective.Renamed     -- Hides 'Over' conflict
+-- > import Papa.Witherable.Renamed    -- Hides 'filter' conflict
+--
+-- == Qualified Imports (internal conflicts)
+--
+-- Some modules have internal conflicts and must be imported qualified:
+--
+-- > import qualified Papa.Containers.Data.Map as Map
+-- > import qualified Papa.Containers.Data.Set as Set
+-- > import qualified Papa.Containers.Data.IntMap as IntMap
+-- > import qualified Papa.Containers.Data.IntSet as IntSet
+-- > import qualified Papa.Containers.Data.Seq as Seq
+-- > import qualified Papa.Containers.Data.Tree as Tree
+-- > import qualified Papa.Free.Control.Monad.Free as Free
+-- > import qualified Papa.Free.Control.Applicative.Free as FreeAp
+-- > import qualified Papa.Free.Control.Comonad.Cofree as Cofree
+-- > import qualified Papa.Id.Data.Id as Id
+-- > import qualified Papa.Id.Data.BiId as BiId
+module Papa (
+  -- * Core Modules
   module Papa.Base,
   module Papa.Bifunctors,
+  module Papa.Comonad.Control.Comonad,
+  module Papa.Comonad.Control.Comonad.Env,
+  module Papa.Comonad.Control.Comonad.Store,
   module Papa.Lens,
-  module Papa.Semigroupoids
+  module Papa.Semigroupoids,
 ) where
 
 import Papa.Base
 import Papa.Bifunctors
+import Papa.Comonad.Control.Comonad
+import Papa.Comonad.Control.Comonad.Env
+import Papa.Comonad.Control.Comonad.Store
 import Papa.Lens
 import Papa.Semigroupoids
diff --git a/src/Papa/Adjunctions.hs b/src/Papa/Adjunctions.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Adjunctions.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Adjunctions (
+  module Papa.Adjunctions.Data.Functor.Adjunction,
+  module Papa.Adjunctions.Data.Functor.Rep,
+) where
+
+import Papa.Adjunctions.Data.Functor.Adjunction
+import Papa.Adjunctions.Data.Functor.Rep
diff --git a/src/Papa/Adjunctions/Data/Functor/Adjunction.hs b/src/Papa/Adjunctions/Data/Functor/Adjunction.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Adjunctions/Data/Functor/Adjunction.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Adjunctions.Data.Functor.Adjunction (
+  module X,
+) where
+
+import Data.Functor.Adjunction as X
diff --git a/src/Papa/Adjunctions/Data/Functor/Rep.hs b/src/Papa/Adjunctions/Data/Functor/Rep.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Adjunctions/Data/Functor/Rep.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Adjunctions.Data.Functor.Rep (
+  module X,
+) where
+
+import Data.Functor.Rep as X
diff --git a/src/Papa/Adjunctions/Renamed.hs b/src/Papa/Adjunctions/Renamed.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Adjunctions/Renamed.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | Re-exports from Papa.Adjunctions with conflicting identifiers hidden.
+--
+-- The 'index' function from Data.Functor.Rep conflicts with Control.Lens.index.
+-- It is hidden from this module. Use 'Data.Functor.Rep.index' directly when needed,
+-- or import qualified:
+-- > import qualified Data.Functor.Rep as Rep
+module Papa.Adjunctions.Renamed (
+  module Papa.Adjunctions.Data.Functor.Adjunction,
+  module Papa.Adjunctions.Data.Functor.Rep,
+) where
+
+import Papa.Adjunctions.Data.Functor.Adjunction
+import Papa.Adjunctions.Data.Functor.Rep hiding (index)
diff --git a/src/Papa/Associative.hs b/src/Papa/Associative.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Associative.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Associative (
+  module Papa.Associative.Data.Associative,
+) where
+
+import Papa.Associative.Data.Associative
diff --git a/src/Papa/Associative/Data/Associative.hs b/src/Papa/Associative/Data/Associative.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Associative/Data/Associative.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Associative.Data.Associative (
+  module X,
+) where
+
+import Data.Associative as X
diff --git a/src/Papa/Associative/Renamed.hs b/src/Papa/Associative/Renamed.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Associative/Renamed.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | Re-exports from Papa.Associative with conflicting identifiers hidden.
+--
+-- Conflicts hidden:
+-- - 'null' (conflicts with Data.Foldable.null)
+-- - 'op' (conflicts with Control.Lens.Wrapped.op)
+--
+-- Use qualified imports when needed:
+-- > import qualified Data.Associative.PartialSemigroupOp as PSO
+-- > import qualified Data.Associative.SemigroupOp as SO
+module Papa.Associative.Renamed (
+  module Papa.Associative.Data.Associative,
+) where
+
+import Papa.Associative.Data.Associative hiding (null, op)
diff --git a/src/Papa/Base.hs b/src/Papa/Base.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base.hs
@@ -0,0 +1,74 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | Papa.Base re-exports core base functionality
+--
+-- Note: The following modules are available but not re-exported to avoid conflicts:
+-- - Papa.Base.Control.Arrow (conflicts with bifunctor first/second)
+-- - Papa.Base.Control.Monad.* (mtl classes conflict with comonad equivalents)
+--
+-- Import them directly if needed:
+-- > import Papa.Base.Control.Arrow
+-- > import Papa.Base.Control.Monad.Reader
+module Papa.Base (
+  module Papa.Base.Control.Applicative,
+  module Papa.Base.Control.Category,
+  module Papa.Base.Control.DeepSeq,
+  module Papa.Base.Control.Monad,
+  module Papa.Base.Data.Bool,
+  module Papa.Base.Data.Char,
+  module Papa.Base.Data.Data,
+  module Papa.Base.Data.Either,
+  module Papa.Base.Data.Eq,
+  module Papa.Base.Data.Foldable,
+  module Papa.Base.Data.Function,
+  module Papa.Base.Data.Functor,
+  module Papa.Base.Data.Int,
+  module Papa.Base.Data.List,
+  module Papa.Base.Data.List.NonEmpty,
+  module Papa.Base.Data.Maybe,
+  module Papa.Base.Data.Monoid,
+  module Papa.Base.Data.Ord,
+  module Papa.Base.Data.Ratio,
+  module Papa.Base.Data.Semigroup,
+  module Papa.Base.Data.Show,
+  module Papa.Base.Data.String,
+  module Papa.Base.Data.Traversable,
+  module Papa.Base.Data.Void,
+  module Papa.Base.GHC.Generics,
+  module Papa.Base.Prelude,
+) where
+
+import Papa.Base.Control.Applicative
+import Papa.Base.Control.Category
+import Papa.Base.Control.DeepSeq
+import Papa.Base.Control.Monad
+import Papa.Base.Data.Bool
+import Papa.Base.Data.Char
+import Papa.Base.Data.Data
+import Papa.Base.Data.Either
+import Papa.Base.Data.Eq
+import Papa.Base.Data.Foldable
+import Papa.Base.Data.Function
+import Papa.Base.Data.Functor
+import Papa.Base.Data.Int
+
+-- Hide uncons/unsnoc on GHC 9.8+ to avoid conflicts with Control.Lens.Cons
+#if MIN_VERSION_base(4,19,0)
+import Papa.Base.Data.List hiding (uncons, unsnoc)
+#else
+import Papa.Base.Data.List
+#endif
+import Papa.Base.Data.List.NonEmpty
+import Papa.Base.Data.Maybe
+import Papa.Base.Data.Monoid
+import Papa.Base.Data.Ord
+import Papa.Base.Data.Ratio
+import Papa.Base.Data.Semigroup
+import Papa.Base.Data.Show
+import Papa.Base.Data.String
+import Papa.Base.Data.Traversable
+import Papa.Base.Data.Void
+import Papa.Base.GHC.Generics
+import Papa.Base.Prelude
diff --git a/src/Papa/Base/Control/Applicative.hs b/src/Papa/Base/Control/Applicative.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Applicative.hs
@@ -0,0 +1,84 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Applicative (
+  Applicative (pure, (<*>), (*>), (<*)),
+  Alternative (empty, (<|>), some, many),
+  Const (Const, getConst),
+  WrappedMonad (unwrapMonad),
+  WrappedArrow (unwrapArrow),
+  ZipList (getZipList),
+  (<$>),
+  (<$),
+  (<**>),
+  liftA,
+  liftA2,
+  liftA3,
+  optional,
+  const,
+  replicateA,
+  replicateA_,
+) where
+
+import Control.Applicative (
+  Alternative (empty, many, some, (<|>)),
+  Applicative (pure, (*>), (<*), (<*>)),
+  Const (Const, getConst),
+  WrappedArrow (unwrapArrow),
+  WrappedMonad (unwrapMonad),
+  ZipList (getZipList),
+  liftA,
+  liftA2,
+  liftA3,
+  optional,
+  (<$),
+  (<$>),
+  (<**>),
+ )
+import Papa.Base.Prelude (IO, Int, Maybe, otherwise, (-), (<=))
+
+{-# INLINE const #-}
+const ::
+  (Applicative f) =>
+  a ->
+  f a
+const =
+  pure
+
+{-# INLINEABLE replicateA #-}
+{-# SPECIALIZE replicateA ::
+  Int ->
+  IO a ->
+  IO [a]
+  #-}
+{-# SPECIALIZE replicateA ::
+  Int ->
+  Maybe a ->
+  Maybe [a]
+  #-}
+replicateA :: (Applicative f) => Int -> f a -> f [a]
+replicateA cnt0 f =
+  loop cnt0
+ where
+  loop cnt
+    | cnt <= 0 = pure []
+    | otherwise = liftA2 (:) f (loop (cnt - 1))
+
+{-# INLINEABLE replicateA_ #-}
+{-# SPECIALIZE replicateA_ ::
+  Int ->
+  IO a ->
+  IO ()
+  #-}
+{-# SPECIALIZE replicateA_ ::
+  Int ->
+  Maybe a ->
+  Maybe ()
+  #-}
+replicateA_ :: (Applicative f) => Int -> f a -> f ()
+replicateA_ cnt0 f =
+  loop cnt0
+ where
+  loop cnt
+    | cnt <= 0 = pure ()
+    | otherwise = f *> loop (cnt - 1)
diff --git a/src/Papa/Base/Control/Arrow.hs b/src/Papa/Base/Control/Arrow.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Arrow.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Arrow (
+  module P,
+) where
+
+import Control.Arrow as P (
+  Arrow (arr, first, second, (&&&), (***)),
+  ArrowApply (app),
+  ArrowChoice (left, right, (+++), (|||)),
+  ArrowLoop (loop),
+  ArrowPlus ((<+>)),
+  ArrowZero (zeroArrow),
+ )
diff --git a/src/Papa/Base/Control/Category.hs b/src/Papa/Base/Control/Category.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Category.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Category (
+  Category (id, (.)),
+) where
+
+import Control.Category (
+  Category (id, (.)),
+ )
diff --git a/src/Papa/Base/Control/DeepSeq.hs b/src/Papa/Base/Control/DeepSeq.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/DeepSeq.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.DeepSeq (
+  module P,
+) where
+
+import Control.DeepSeq as P (
+  NFData (rnf),
+  deepseq,
+  force,
+ )
diff --git a/src/Papa/Base/Control/Monad.hs b/src/Papa/Base/Control/Monad.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Monad.hs
@@ -0,0 +1,104 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Monad (
+  Functor (fmap),
+  Monad ((>>=), return, (>>)),
+  MonadFail (fail),
+  MonadFix (mfix),
+  MonadPlus (mzero, mplus),
+  MonadZip (mzip, mzipWith, munzip),
+  forever,
+  msum,
+  mfilter,
+  filterM,
+  foldM,
+  foldM_,
+  replicateM,
+  replicateM_,
+  guard,
+  when,
+  unless,
+  (<$!>),
+  anyM,
+  allM,
+  findM,
+) where
+
+import Control.Monad (
+  Functor (fmap),
+  Monad (return, (>>), (>>=)),
+  MonadFail (fail),
+  MonadPlus (mplus, mzero),
+  filterM,
+  foldM,
+  foldM_,
+  forever,
+  guard,
+  mfilter,
+  msum,
+  replicateM,
+  replicateM_,
+  unless,
+  when,
+  (<$!>),
+ )
+import Control.Monad.Fix as P (
+  MonadFix (mfix),
+ )
+import Control.Monad.Zip as P (
+  MonadZip (munzip, mzip, mzipWith),
+ )
+
+import Data.Bool (Bool (False, True))
+import Data.Maybe (Maybe (Just, Nothing))
+
+{-# INLINE anyM #-}
+anyM ::
+  (Monad m) =>
+  (a -> m Bool) ->
+  [a] ->
+  m Bool
+anyM _ [] =
+  return False
+anyM f (a : as) =
+  do
+    z <- f a
+    if z
+      then return True
+      else anyM f as
+
+{-# INLINE allM #-}
+allM ::
+  (Monad m) =>
+  (a -> m Bool) ->
+  [a] ->
+  m Bool
+allM _ [] =
+  return True
+allM f (a : as) =
+  do
+    z <- f a
+    if z
+      then allM f as
+      else return False
+
+{-# INLINE findM #-}
+
+-- | Find an element satisfying a predicate
+findM ::
+  (Monad m) =>
+  (a -> m Bool) ->
+  [a] ->
+  m (Maybe a)
+findM _ [] =
+  return Nothing
+findM f (x : xs) =
+  do
+    b <- f x
+    if b
+      then
+        return (Just x)
+      else
+        findM f xs
diff --git a/src/Papa/Base/Control/Monad/Cont.hs b/src/Papa/Base/Control/Monad/Cont.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Monad/Cont.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Monad.Cont (
+  module P,
+) where
+
+import Control.Monad.Cont.Class as P (
+  MonadCont (callCC),
+ )
diff --git a/src/Papa/Base/Control/Monad/Error.hs b/src/Papa/Base/Control/Monad/Error.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Monad/Error.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Monad.Error (
+  module P,
+) where
+
+import Control.Monad.Except as P (
+  MonadError (catchError, throwError),
+ )
diff --git a/src/Papa/Base/Control/Monad/RWS.hs b/src/Papa/Base/Control/Monad/RWS.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Monad/RWS.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Monad.RWS (
+  module P,
+) where
+
+import Control.Monad.RWS.Class as P (
+  MonadRWS,
+ )
diff --git a/src/Papa/Base/Control/Monad/Reader.hs b/src/Papa/Base/Control/Monad/Reader.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Monad/Reader.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Monad.Reader (
+  module P,
+) where
+
+import Control.Monad.Reader.Class as P (
+  MonadReader (ask, local, reader),
+ )
diff --git a/src/Papa/Base/Control/Monad/State.hs b/src/Papa/Base/Control/Monad/State.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Monad/State.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Monad.State (
+  module P,
+) where
+
+import Control.Monad.State.Class as P (
+  MonadState (get, put, state),
+ )
diff --git a/src/Papa/Base/Control/Monad/Trans.hs b/src/Papa/Base/Control/Monad/Trans.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Monad/Trans.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Monad.Trans (
+  module P,
+) where
+
+import Control.Monad.IO.Class as P (
+  MonadIO (liftIO),
+ )
+import Control.Monad.Trans.Class as P (
+  MonadTrans (lift),
+ )
diff --git a/src/Papa/Base/Control/Monad/Writer.hs b/src/Papa/Base/Control/Monad/Writer.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Control/Monad/Writer.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Control.Monad.Writer (
+  module P,
+) where
+
+import Control.Monad.Writer.Class as P (
+  MonadWriter (listen, pass, tell, writer),
+ )
diff --git a/src/Papa/Base/Data/Bool.hs b/src/Papa/Base/Data/Bool.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Bool.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Bool (
+  module P,
+) where
+
+import Data.Bool as P (
+  bool,
+  not,
+  otherwise,
+  (&&),
+  (||),
+ )
diff --git a/src/Papa/Base/Data/Char.hs b/src/Papa/Base/Data/Char.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Char.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Char (
+  module P,
+) where
+
+import Data.Char as P (
+  Char,
+  GeneralCategory (ClosePunctuation, ConnectorPunctuation, Control, CurrencySymbol, DashPunctuation, DecimalNumber, EnclosingMark, FinalQuote, Format, InitialQuote, LetterNumber, LineSeparator, LowercaseLetter, MathSymbol, ModifierLetter, ModifierSymbol, NonSpacingMark, NotAssigned, OpenPunctuation, OtherLetter, OtherNumber, OtherPunctuation, OtherSymbol, ParagraphSeparator, PrivateUse, Space, SpacingCombiningMark, Surrogate, TitlecaseLetter, UppercaseLetter),
+  chr,
+  isAlpha,
+  isAlphaNum,
+  isAscii,
+  isAsciiLower,
+  isAsciiUpper,
+  isControl,
+  isDigit,
+  isHexDigit,
+  isLatin1,
+  isLetter,
+  isLower,
+  isMark,
+  isNumber,
+  isOctDigit,
+  isPrint,
+  isPunctuation,
+  isSeparator,
+  isSpace,
+  isSymbol,
+  isUpper,
+  ord,
+  toLower,
+  toTitle,
+  toUpper,
+ )
diff --git a/src/Papa/Base/Data/Data.hs b/src/Papa/Base/Data/Data.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Data.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Data (
+  module P,
+) where
+
+import Data.Data as P (
+  Data,
+  Typeable,
+ )
diff --git a/src/Papa/Base/Data/Either.hs b/src/Papa/Base/Data/Either.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Either.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Either (
+  module P,
+  lefts,
+  rights,
+  fromLeft,
+  fromRight,
+) where
+
+import Control.Applicative (Applicative (pure))
+import Control.Category (Category (id, (.)))
+import Control.Lens (Traversal, _Left, _Right)
+import Data.Either as P (
+  Either (Left, Right),
+  either,
+  partitionEithers,
+ )
+import Data.Traversable (Traversable (traverse))
+
+{-# INLINE lefts #-}
+lefts :: (Traversable f) => Traversal (f (Either a b)) (f (Either a' b)) a a'
+lefts = traverse . _Left
+
+{-# INLINE rights #-}
+rights :: (Traversable f) => Traversal (f (Either a b)) (f (Either a b')) b b'
+rights = traverse . _Right
+
+{-# INLINE fromLeft #-}
+fromLeft :: a -> Either a b -> a
+fromLeft x = either id (pure x)
+
+{-# INLINE fromRight #-}
+fromRight :: b -> Either a b -> b
+fromRight x = either (pure x) id
diff --git a/src/Papa/Base/Data/Eq.hs b/src/Papa/Base/Data/Eq.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Eq.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Eq (
+  module P,
+  module Q,
+) where
+
+import Data.Eq as P (
+  Eq ((/=), (==)),
+ )
+import Data.Functor.Classes as Q (
+  Eq1 (liftEq),
+  Eq2 (liftEq2),
+ )
diff --git a/src/Papa/Base/Data/Foldable.hs b/src/Papa/Base/Data/Foldable.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Foldable.hs
@@ -0,0 +1,77 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Foldable (
+  module P,
+  mapM_,
+  forM_,
+  sequence_,
+) where
+
+import Data.Foldable as P (
+  Foldable (elem, fold, foldMap, foldl, foldl', foldr, foldr', null, product, sum, toList),
+  all,
+  and,
+  any,
+  asum,
+  find,
+  foldlM,
+  foldrM,
+  for_,
+  notElem,
+  or,
+  sequenceA_,
+  traverse_,
+ )
+
+import Control.Applicative (Applicative)
+import Data.Foldable ()
+
+{-# INLINE mapM_ #-}
+
+-- | Map each element to an action, evaluate these actions left to right, and ignore the results.
+--
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> mapM_ (\x -> Just x) [1,2,3]
+-- Just ()
+-- >>> mapM_ (\_ -> Nothing) [1,2,3]
+-- Nothing
+mapM_ ::
+  (Foldable t, Applicative f) =>
+  (a -> f b) ->
+  t a ->
+  f ()
+mapM_ =
+  traverse_
+
+{-# INLINE forM_ #-}
+
+-- | 'forM_' is 'mapM_' with its arguments flipped.
+--
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> forM_ [1,2,3] (\x -> Just x)
+-- Just ()
+forM_ ::
+  (Foldable t, Applicative m) =>
+  t a ->
+  (a -> m b) ->
+  m ()
+forM_ a f =
+  mapM_ f a
+
+{-# INLINE sequence_ #-}
+
+-- | Evaluate each action in the structure left to right, and ignore the results.
+--
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> sequence_ [Just 1, Just 2, Just 3]
+-- Just ()
+-- >>> sequence_ [Just 1, Nothing, Just 3]
+-- Nothing
+sequence_ ::
+  (Foldable t, Applicative f) =>
+  t (f a) ->
+  f ()
+sequence_ =
+  sequenceA_
diff --git a/src/Papa/Base/Data/Function.hs b/src/Papa/Base/Data/Function.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Function.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Function (
+  module P,
+  flip,
+) where
+
+import Data.Function as P (
+  fix,
+  on,
+  ($),
+  (&),
+ )
+
+import Data.Functor (Functor (fmap))
+
+{-# INLINE flip #-}
+
+-- | Apply a functorial function to a value.
+--
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> flip (Just (\x -> x)) 5
+-- Just 5
+-- >>> flip [(\x -> x), (\x -> x)] 3
+-- [3,3]
+flip ::
+  (Functor f) =>
+  f (a -> b) ->
+  a ->
+  f b
+flip f a =
+  fmap (\k -> k a) f
diff --git a/src/Papa/Base/Data/Functor.hs b/src/Papa/Base/Data/Functor.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Functor.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE CPP #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Functor (
+  module P,
+  map,
+) where
+
+import Data.Functor as P (
+  Functor (fmap, (<$)),
+  void,
+  ($>),
+  (<$>),
+#if MIN_VERSION_base(4,11,0)
+  (<&>),
+#endif
+ )
+
+{-# INLINE map #-}
+
+-- | Map a function over a functor.
+--
+-- >>> map (\x -> x) [1,2,3]
+-- [1,2,3]
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> map (\x -> x) (Just 5)
+-- Just 5
+-- >>> map (\x -> x) Nothing
+-- Nothing
+map ::
+  (Functor f) =>
+  (a -> b) ->
+  f a ->
+  f b
+map =
+  fmap
diff --git a/src/Papa/Base/Data/Int.hs b/src/Papa/Base/Data/Int.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Int.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Int (
+  module P,
+) where
+
+import Data.Int as P (
+  Int,
+  Int16,
+  Int32,
+  Int64,
+  Int8,
+ )
diff --git a/src/Papa/Base/Data/List.hs b/src/Papa/Base/Data/List.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/List.hs
@@ -0,0 +1,122 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE CPP #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.List (
+  module P,
+  lookup,
+  (++),
+) where
+
+import Data.List as P (
+  all,
+  and,
+  any,
+  break,
+  cycle,
+  delete,
+  deleteBy,
+  deleteFirstsBy,
+  drop,
+  dropWhile,
+  dropWhileEnd,
+  elem,
+  find,
+  foldl,
+  foldl',
+  foldr,
+  genericDrop,
+  genericLength,
+  genericReplicate,
+  genericSplitAt,
+  genericTake,
+  insertBy,
+  intercalate,
+  intersect,
+  intersectBy,
+  intersperse,
+  isInfixOf,
+  isPrefixOf,
+  isSubsequenceOf,
+  isSuffixOf,
+  length,
+  lines,
+  mapAccumL,
+  mapAccumR,
+  notElem,
+  nub,
+  nubBy,
+  null,
+  or,
+  partition,
+  permutations,
+  product,
+  replicate,
+  reverse,
+  sort,
+  sortBy,
+  sortOn,
+  span,
+  splitAt,
+  stripPrefix,
+  subsequences,
+  sum,
+  take,
+  takeWhile,
+  transpose,
+  union,
+  unionBy,
+  unlines,
+  unwords,
+  words,
+  (\\),
+#if MIN_VERSION_base(4,19,0)
+  -- Added in base 4.19 (GHC 9.8)
+  singleton,
+  uncons,
+  unsnoc,
+  (!?),
+#endif
+ )
+
+import Data.Eq (Eq ((==)))
+import Data.Foldable (Foldable)
+import Data.Maybe (Maybe (Just, Nothing))
+import Data.Semigroup (Semigroup ((<>)))
+
+{-# INLINE lookup #-}
+
+-- | Look up a key in an association list.
+--
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> lookup 2 [(1,'a'), (2,'b'), (3,'c')]
+-- Just 'b'
+-- >>> lookup 4 [(1,'a'), (2,'b'), (3,'c')]
+-- Nothing
+lookup ::
+  (Eq a, Foldable f) =>
+  a ->
+  f (a, b) ->
+  Maybe b
+lookup a =
+  foldr (\(x, y) b -> if x == a then Just y else b) Nothing
+
+{-# SPECIALIZE (++) ::
+  [a] ->
+  [a] ->
+  [a]
+  #-}
+
+-- | Append two semigroups.
+--
+-- >>> [1,2] ++ [3,4]
+-- [1,2,3,4]
+-- >>> "hello" ++ " world"
+-- "hello world"
+(++) ::
+  (Semigroup a) =>
+  a ->
+  a ->
+  a
+(++) =
+  (<>)
diff --git a/src/Papa/Base/Data/List/NonEmpty.hs b/src/Papa/Base/Data/List/NonEmpty.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/List/NonEmpty.hs
@@ -0,0 +1,107 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+{- HLINT ignore "Avoid restricted function" -}
+
+module Papa.Base.Data.List.NonEmpty (
+  module P,
+  head,
+  tail,
+  last,
+  init,
+) where
+
+import Control.Lens (Lens')
+import Data.Functor (Functor (fmap))
+import Data.List.NonEmpty as P (
+  NonEmpty ((:|)),
+  group,
+  group1,
+  groupAllWith,
+  groupAllWith1,
+  groupBy,
+  groupBy1,
+  groupWith,
+  groupWith1,
+  inits,
+  insert,
+  iterate,
+  nonEmpty,
+  repeat,
+  scanl,
+  scanl1,
+  scanr,
+  scanr1,
+  some1,
+  tails,
+  unfold,
+  xor,
+ )
+import qualified Data.List.NonEmpty as NE
+import Data.Semigroup ((<>))
+
+-- | Lens to the head (first element) of a 'NonEmpty' list.
+--
+-- >>> import Control.Lens
+-- >>> let ne = 1 :| [2,3,4]
+-- >>> ne ^. head
+-- 1
+-- >>> ne & head .~ 99
+-- 99 :| [2,3,4]
+-- >>> ne & head %~ (\x -> x)
+-- 1 :| [2,3,4]
+{-# INLINE head #-}
+head :: Lens' (NonEmpty a) a
+head f (h :| t) = fmap (:| t) (f h)
+
+-- | Lens to the tail (all elements except the first) of a 'NonEmpty' list.
+--
+-- >>> import Control.Lens
+-- >>> let ne = 1 :| [2,3,4]
+-- >>> ne ^. tail
+-- [2,3,4]
+-- >>> ne & tail .~ [99]
+-- 1 :| [99]
+-- >>> ne & tail .~ []
+-- 1 :| []
+{-# INLINE tail #-}
+tail :: Lens' (NonEmpty a) [a]
+tail f (h :| t) = fmap (h :|) (f t)
+
+-- | Lens to the last element of a 'NonEmpty' list.
+--
+-- >>> import Control.Lens
+-- >>> let ne = 1 :| [2,3,4]
+-- >>> ne ^. last
+-- 4
+-- >>> ne & last .~ 99
+-- 1 :| [2,3,99]
+-- >>> (1 :| []) ^. last
+-- 1
+-- >>> (1 :| []) & last .~ 99
+-- 99 :| []
+{-# INLINE last #-}
+last :: Lens' (NonEmpty a) a
+last f (h :| []) = fmap (:| []) (f h)
+last f (h :| (x : xs)) = fmap (\(y :| ys) -> h :| (y : ys)) (last f (x :| xs))
+
+-- | Lens to the init (all elements except the last) of a 'NonEmpty' list.
+--
+-- >>> import Control.Lens
+-- >>> let ne = 1 :| [2,3,4]
+-- >>> ne ^. init
+-- [1,2,3]
+-- >>> ne & init .~ [99]
+-- 99 :| [4]
+-- >>> ne & init .~ []
+-- 4 :| []
+-- >>> (1 :| []) ^. init
+-- []
+-- >>> (1 :| []) & init .~ [10,20]
+-- 10 :| [20,1]
+{-# INLINE init #-}
+init :: Lens' (NonEmpty a) [a]
+init f ne = fmap rebuild (f (NE.init ne))
+ where
+  rebuild [] = NE.last ne :| []
+  rebuild (x : xs) = x :| (xs <> [NE.last ne])
diff --git a/src/Papa/Base/Data/Maybe.hs b/src/Papa/Base/Data/Maybe.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Maybe.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Maybe (
+  module P,
+) where
+
+import Data.Maybe as P (
+  Maybe (Just, Nothing),
+  fromMaybe,
+  maybe,
+ )
diff --git a/src/Papa/Base/Data/Monoid.hs b/src/Papa/Base/Data/Monoid.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Monoid.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Monoid (
+  module P,
+  mconcat,
+) where
+
+import Data.Monoid as P (
+  Monoid (mappend, mempty),
+ )
+
+import Data.Foldable (Foldable, fold)
+
+{-# INLINE mconcat #-}
+
+-- | Fold a list using the monoid.
+--
+-- >>> mconcat [[1,2], [3,4], [5,6]]
+-- [1,2,3,4,5,6]
+-- >>> mconcat ["hello", " ", "world"]
+-- "hello world"
+mconcat ::
+  (Monoid a, Foldable f) =>
+  f a ->
+  a
+mconcat =
+  fold
diff --git a/src/Papa/Base/Data/Ord.hs b/src/Papa/Base/Data/Ord.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Ord.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Ord (
+  module P,
+  module Q,
+) where
+
+import Data.Functor.Classes as Q (
+  Ord1 (liftCompare),
+  Ord2 (liftCompare2),
+ )
+import Data.Ord as P (
+  Down (Down),
+  Ord (compare, max, min, (<), (<=), (>), (>=)),
+  comparing,
+ )
diff --git a/src/Papa/Base/Data/Ratio.hs b/src/Papa/Base/Data/Ratio.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Ratio.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Ratio (
+  module P,
+) where
+
+import Data.Ratio as P (
+  Ratio,
+  Rational,
+  approxRational,
+  denominator,
+  numerator,
+  (%),
+ )
diff --git a/src/Papa/Base/Data/Semigroup.hs b/src/Papa/Base/Data/Semigroup.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Semigroup.hs
@@ -0,0 +1,30 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Semigroup (
+  module P,
+) where
+
+import Data.Semigroup as P (
+  All (getAll),
+  Any (getAny),
+  Arg (Arg),
+  ArgMax,
+  ArgMin,
+  Dual (getDual),
+  Endo (appEndo),
+  First (getFirst),
+  Last (getLast),
+  Max (getMax),
+  Min (getMin),
+  Product (getProduct),
+  Semigroup (sconcat, stimes, (<>)),
+  Sum (getSum),
+  WrappedMonoid (unwrapMonoid),
+  cycle1,
+  diff,
+  mtimesDefault,
+  stimesIdempotent,
+  stimesIdempotentMonoid,
+  stimesMonoid,
+ )
diff --git a/src/Papa/Base/Data/Show.hs b/src/Papa/Base/Data/Show.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Show.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Show (
+  module P,
+  module Q,
+) where
+
+import Data.Functor.Classes as Q (
+  Show1 (liftShowsPrec),
+  Show2 (liftShowsPrec2),
+ )
+import Prelude as P (
+  Show (show, showsPrec),
+  ShowS,
+  showString,
+  shows,
+ )
diff --git a/src/Papa/Base/Data/String.hs b/src/Papa/Base/Data/String.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/String.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.String (
+  module P,
+) where
+
+import Data.String as P (
+  String,
+  lines,
+  unlines,
+  unwords,
+  words,
+ )
diff --git a/src/Papa/Base/Data/Traversable.hs b/src/Papa/Base/Data/Traversable.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Traversable.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Traversable (
+  module P,
+  mapM,
+  forM,
+  sequence,
+) where
+
+import Data.Traversable as P (
+  Traversable (sequenceA, traverse),
+  fmapDefault,
+  foldMapDefault,
+  for,
+  mapAccumL,
+ )
+
+import Control.Applicative (Applicative)
+
+{-# INLINE mapM #-}
+
+-- | Map each element to an action, evaluate these actions left to right, and collect the results.
+--
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> mapM (\x -> Just x) [1,2,3]
+-- Just [1,2,3]
+-- >>> mapM (\_ -> Nothing) [1,2,3]
+-- Nothing
+mapM ::
+  (Traversable t, Applicative f) =>
+  (a -> f b) ->
+  t a ->
+  f (t b)
+mapM =
+  traverse
+
+{-# INLINE forM #-}
+
+-- | 'forM' is 'mapM' with its arguments flipped.
+--
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> forM [1,2,3] (\x -> Just x)
+-- Just [1,2,3]
+forM ::
+  (Traversable t, Applicative f) =>
+  t a ->
+  (a -> f b) ->
+  f (t b)
+forM a f =
+  traverse f a
+
+{-# INLINE sequence #-}
+
+-- | Evaluate each action in the structure left to right, and collect the results.
+--
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> sequence [Just 1, Just 2, Just 3]
+-- Just [1,2,3]
+-- >>> sequence [Just 1, Nothing, Just 3]
+-- Nothing
+sequence ::
+  (Traversable t, Applicative f) =>
+  t (f a) ->
+  f (t a)
+sequence =
+  sequenceA
diff --git a/src/Papa/Base/Data/Void.hs b/src/Papa/Base/Data/Void.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Data/Void.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Data.Void (
+  module P,
+) where
+
+import Data.Void as P (
+  Void,
+  absurd,
+  vacuous,
+ )
diff --git a/src/Papa/Base/GHC/Generics.hs b/src/Papa/Base/GHC/Generics.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/GHC/Generics.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.GHC.Generics (
+  module P,
+) where
+
+import GHC.Generics as P (
+  Generic,
+  Generic1,
+ )
diff --git a/src/Papa/Base/Prelude.hs b/src/Papa/Base/Prelude.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Base/Prelude.hs
@@ -0,0 +1,189 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Base.Prelude (
+  module P,
+) where
+
+import Prelude as P (
+  Applicative,
+  Bool (
+    False,
+    True
+  ),
+  Char,
+  Double,
+  Either (
+    Left,
+    Right
+  ),
+  Enum,
+  Eq,
+  FilePath,
+  Float,
+  Floating,
+  Foldable,
+  Fractional,
+  Functor,
+  IO,
+  IOError,
+  Int,
+  Integer,
+  Integral,
+  Maybe (
+    Just,
+    Nothing
+  ),
+  Monad,
+  Monoid,
+  Num,
+  Ord,
+  Ordering (
+    EQ,
+    GT,
+    LT
+  ),
+  Rational,
+  Real,
+  RealFloat,
+  Show,
+  ShowS,
+  Traversable,
+  Word,
+  abs,
+  acos,
+  acosh,
+  all,
+  and,
+  any,
+  appendFile,
+  asin,
+  asinh,
+  atan,
+  atan2,
+  atanh,
+  break,
+  ceiling,
+  compare,
+  cos,
+  cosh,
+  curry,
+  cycle,
+  decodeFloat,
+  divMod,
+  drop,
+  dropWhile,
+  either,
+  elem,
+  encodeFloat,
+  even,
+  exp,
+  exponent,
+  filter,
+  floatDigits,
+  floatRadix,
+  floatRange,
+  floor,
+  fmap,
+  foldMap,
+  foldl,
+  foldr,
+  fromInteger,
+  fromIntegral,
+  fromRational,
+  gcd,
+  getChar,
+  getContents,
+  getLine,
+  interact,
+  ioError,
+  isDenormalized,
+  isIEEE,
+  isInfinite,
+  isNaN,
+  isNegativeZero,
+  lcm,
+  lines,
+  log,
+  logBase,
+  max,
+  maybe,
+  mempty,
+  min,
+  mod,
+  negate,
+  not,
+  notElem,
+  null,
+  odd,
+  otherwise,
+  pi,
+  product,
+  properFraction,
+  pure,
+  putChar,
+  putStr,
+  putStrLn,
+  quot,
+  quotRem,
+  readFile,
+  readIO,
+  realToFrac,
+  recip,
+  rem,
+  replicate,
+  round,
+  scaleFloat,
+  sequenceA,
+  show,
+  showParen,
+  shows,
+  showsPrec,
+  significand,
+  signum,
+  sin,
+  sinh,
+  span,
+  splitAt,
+  sqrt,
+  subtract,
+  sum,
+  take,
+  takeWhile,
+  tan,
+  tanh,
+  toInteger,
+  toRational,
+  traverse,
+  truncate,
+  uncurry,
+  unlines,
+  until,
+  unwords,
+  unzip3,
+  words,
+  writeFile,
+  zip,
+  zip3,
+  zipWith,
+  zipWith3,
+  ($),
+  (&&),
+  (*),
+  (**),
+  (+),
+  (-),
+  (/),
+  (/=),
+  (<),
+  (<$),
+  (<$>),
+  (<*>),
+  (<=),
+  (==),
+  (>),
+  (>=),
+  (^),
+  (^^),
+  (||),
+ )
diff --git a/src/Papa/Bifunctors.hs b/src/Papa/Bifunctors.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Bifunctors.hs
@@ -0,0 +1,38 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Bifunctors (
+  module P,
+  biconcat,
+  biconcatMap,
+) where
+
+import Data.Biapplicative as P (Biapplicative (bipure, (*>>), (<<*), (<<*>>)), biliftA2, biliftA3, (<<$>>), (<<**>>))
+import Data.Bifoldable as P (Bifoldable (bifold, bifoldMap), biList, biall, biand, biany, biasum, bielem, bifind, bifoldl, bifoldl', bifoldlM, bifoldr, bifoldr', bifoldrM, biforM_, bifor_, bilength, bimapM_, bimsum, binotElem, binull, bior, biproduct, bisequenceA_, bisequence_, bisum, bitraverse_)
+import Data.Bifunctor.Biff as P (Biff (runBiff))
+import Data.Bifunctor.Clown as P (Clown (runClown))
+import Data.Bifunctor.Fix as P (Fix (out))
+import Data.Bifunctor.Flip as P (Flip (runFlip))
+import Data.Bifunctor.Functor as P (BifunctorComonad (biduplicate, biextend, biextract), BifunctorFunctor (bifmap), BifunctorMonad (bibind, bijoin, bireturn), biliftM, biliftW)
+import Data.Bifunctor.Join as P (Join (Join, runJoin))
+import Data.Bifunctor.Joker as P (Joker (Joker, runJoker))
+import Data.Bifunctor.Tannen as P (Tannen (Tannen, runTannen))
+import Data.Bifunctor.Wrapped as P (WrappedBifunctor (WrapBifunctor, unwrapBifunctor))
+import Data.Bitraversable as P (Bitraversable (bitraverse), bifoldMapDefault, bifor, biforM, bimapAccumL, bimapAccumR, bimapDefault, bimapM, bisequence, bisequenceA)
+import Data.Monoid (Monoid)
+
+biconcat ::
+  (Bifoldable p, Monoid m) =>
+  p m m ->
+  m
+biconcat =
+  bifold
+
+biconcatMap ::
+  (Bifoldable p, Monoid m) =>
+  (a -> m) ->
+  (b -> m) ->
+  p a b ->
+  m
+biconcatMap =
+  bifoldMap
diff --git a/src/Papa/Bifunctors/Data/Bifoldable.hs b/src/Papa/Bifunctors/Data/Bifoldable.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Bifunctors/Data/Bifoldable.hs
@@ -0,0 +1,40 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Bifunctors.Data.Bifoldable (
+  biconcat,
+  biconcatMap,
+) where
+
+import Data.Bifoldable (Bifoldable (bifold, bifoldMap))
+import Data.Monoid (Monoid)
+
+{-# INLINE biconcat #-}
+
+-- | Fold a bifunctor containing monoids.
+--
+-- >>> biconcat ([1,2], [3,4])
+-- [1,2,3,4]
+-- >>> biconcat ("hello", " world")
+-- "hello world"
+biconcat ::
+  (Bifoldable p, Monoid m) =>
+  p m m ->
+  m
+biconcat =
+  bifold
+
+{-# INLINE biconcatMap #-}
+
+-- | Map each side of a bifunctor to a monoid and combine.
+--
+-- >>> biconcatMap (\x -> [x]) (\x -> [x]) (1, 2)
+-- [1,2]
+biconcatMap ::
+  (Bifoldable p, Monoid m) =>
+  (a -> m) ->
+  (b -> m) ->
+  p a b ->
+  m
+biconcatMap =
+  bifoldMap
diff --git a/src/Papa/Comonad.hs b/src/Papa/Comonad.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Comonad.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Comonad (
+  module Papa.Comonad.Control.Comonad,
+  module Papa.Comonad.Control.Comonad.Env,
+  module Papa.Comonad.Control.Comonad.Store,
+  module Papa.Comonad.Control.Comonad.Traced,
+) where
+
+import Papa.Comonad.Control.Comonad
+import Papa.Comonad.Control.Comonad.Env
+import Papa.Comonad.Control.Comonad.Store
+import Papa.Comonad.Control.Comonad.Traced
diff --git a/src/Papa/Comonad/Control/Comonad.hs b/src/Papa/Comonad/Control/Comonad.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Comonad/Control/Comonad.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Comonad.Control.Comonad (
+  module X,
+) where
+
+import Control.Comonad as X
diff --git a/src/Papa/Comonad/Control/Comonad/Env.hs b/src/Papa/Comonad/Control/Comonad/Env.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Comonad/Control/Comonad/Env.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Comonad.Control.Comonad.Env (
+  module X,
+) where
+
+import Control.Comonad.Env as X
diff --git a/src/Papa/Comonad/Control/Comonad/Store.hs b/src/Papa/Comonad/Control/Comonad/Store.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Comonad/Control/Comonad/Store.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Comonad.Control.Comonad.Store (
+  module X,
+) where
+
+import Control.Comonad.Store as X
diff --git a/src/Papa/Comonad/Control/Comonad/Traced.hs b/src/Papa/Comonad/Control/Comonad/Traced.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Comonad/Control/Comonad/Traced.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Comonad.Control.Comonad.Traced (
+  module X,
+) where
+
+import Control.Comonad.Traced as X
diff --git a/src/Papa/Comonad/Renamed.hs b/src/Papa/Comonad/Renamed.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Comonad/Renamed.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | Re-exports from Papa.Comonad.
+--
+-- Note: The comonad package does not re-export conflicting Monoid/Semigroup
+-- identifiers, so no hiding is necessary. This module exists for consistency
+-- with other Papa.*.Renamed modules.
+module Papa.Comonad.Renamed (
+  module Papa.Comonad.Control.Comonad,
+  module Papa.Comonad.Control.Comonad.Env,
+  module Papa.Comonad.Control.Comonad.Store,
+  module Papa.Comonad.Control.Comonad.Traced,
+) where
+
+import Papa.Comonad.Control.Comonad
+import Papa.Comonad.Control.Comonad.Env
+import Papa.Comonad.Control.Comonad.Store
+import Papa.Comonad.Control.Comonad.Traced
diff --git a/src/Papa/Containers.hs b/src/Papa/Containers.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Containers.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | This module cannot re-export all submodules due to name conflicts.
+-- Import the specific container types qualified instead:
+--
+-- > import qualified Papa.Containers.Data.Map as Map
+-- > import qualified Papa.Containers.Data.Set as Set
+-- > import qualified Papa.Containers.Data.IntMap as IntMap
+-- > import qualified Papa.Containers.Data.IntSet as IntSet
+-- > import qualified Papa.Containers.Data.Seq as Seq
+-- > import qualified Papa.Containers.Data.Tree as Tree
+module Papa.Containers () where
+
+-- Intentionally empty due to name conflicts between Map, IntMap, Set, IntSet, etc.
diff --git a/src/Papa/Containers/Data/IntMap.hs b/src/Papa/Containers/Data/IntMap.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Containers/Data/IntMap.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Containers.Data.IntMap (
+  module X,
+) where
+
+import Data.IntMap.Strict as X
diff --git a/src/Papa/Containers/Data/IntSet.hs b/src/Papa/Containers/Data/IntSet.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Containers/Data/IntSet.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Containers.Data.IntSet (
+  module X,
+) where
+
+import Data.IntSet as X
diff --git a/src/Papa/Containers/Data/Map.hs b/src/Papa/Containers/Data/Map.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Containers/Data/Map.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Containers.Data.Map (
+  module X,
+) where
+
+import Data.Map.Strict as X
diff --git a/src/Papa/Containers/Data/Seq.hs b/src/Papa/Containers/Data/Seq.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Containers/Data/Seq.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Containers.Data.Seq (
+  module X,
+) where
+
+import Data.Sequence as X
diff --git a/src/Papa/Containers/Data/Set.hs b/src/Papa/Containers/Data/Set.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Containers/Data/Set.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Containers.Data.Set (
+  module X,
+) where
+
+import Data.Set as X
diff --git a/src/Papa/Containers/Data/Tree.hs b/src/Papa/Containers/Data/Tree.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Containers/Data/Tree.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Containers.Data.Tree (
+  module X,
+) where
+
+import Data.Tree as X
diff --git a/src/Papa/Contravariant.hs b/src/Papa/Contravariant.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Contravariant.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Contravariant (
+  module Papa.Contravariant.Data.Functor.Contravariant,
+) where
+
+import Papa.Contravariant.Data.Functor.Contravariant
diff --git a/src/Papa/Contravariant/Data/Functor/Contravariant.hs b/src/Papa/Contravariant/Data/Functor/Contravariant.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Contravariant/Data/Functor/Contravariant.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Contravariant.Data.Functor.Contravariant (
+  module X,
+) where
+
+import Data.Functor.Contravariant as X (
+  Contravariant (contramap),
+ )
+import Data.Functor.Contravariant.Divisible as X (
+  Decidable (choose, lose),
+  Divisible (conquer, divide),
+ )
diff --git a/src/Papa/Distributive.hs b/src/Papa/Distributive.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Distributive.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Distributive (
+  module Papa.Distributive.Data.Distributive,
+) where
+
+import Papa.Distributive.Data.Distributive
diff --git a/src/Papa/Distributive/Data/Distributive.hs b/src/Papa/Distributive/Data/Distributive.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Distributive/Data/Distributive.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Distributive.Data.Distributive (
+  module X,
+) where
+
+import Data.Distributive as X (
+  Distributive (collect, distribute),
+ )
diff --git a/src/Papa/Free.hs b/src/Papa/Free.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Free.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | This module cannot re-export all submodules due to name conflicts.
+-- Import the specific Free types qualified instead:
+--
+-- > import qualified Papa.Free.Control.Monad.Free as Free
+-- > import qualified Papa.Free.Control.Applicative.Free as FreeAp
+-- > import qualified Papa.Free.Control.Comonad.Cofree as Cofree
+module Papa.Free () where
+
+-- Intentionally empty due to name conflicts (Pure constructor in both Free and FreeAp)
diff --git a/src/Papa/Free/Control/Applicative/Free.hs b/src/Papa/Free/Control/Applicative/Free.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Free/Control/Applicative/Free.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Free.Control.Applicative.Free (
+  module X,
+) where
+
+import Control.Applicative.Free as X
diff --git a/src/Papa/Free/Control/Comonad/Cofree.hs b/src/Papa/Free/Control/Comonad/Cofree.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Free/Control/Comonad/Cofree.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Free.Control.Comonad.Cofree (
+  module X,
+) where
+
+import Control.Comonad.Cofree as X
diff --git a/src/Papa/Free/Control/Monad/Free.hs b/src/Papa/Free/Control/Monad/Free.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Free/Control/Monad/Free.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Free.Control.Monad.Free (
+  module X,
+) where
+
+import Control.Monad.Free as X
diff --git a/src/Papa/Id.hs b/src/Papa/Id.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Id.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | This module cannot re-export all submodules due to name conflicts.
+-- Import the specific Id types qualified instead:
+--
+-- > import qualified Papa.Id.Data.Id as Id
+-- > import qualified Papa.Id.Data.BiId as BiId
+module Papa.Id () where
+
+-- Intentionally empty due to name conflicts between Id and BiId (__Wrapped)
diff --git a/src/Papa/Id/Data/BiId.hs b/src/Papa/Id/Data/BiId.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Id/Data/BiId.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Id.Data.BiId (
+  module X,
+) where
+
+import Data.BiId as X
diff --git a/src/Papa/Id/Data/Id.hs b/src/Papa/Id/Data/Id.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Id/Data/Id.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Id.Data.Id (
+  module X,
+) where
+
+import Data.Id as X
diff --git a/src/Papa/Lens.hs b/src/Papa/Lens.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Lens.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Lens (
+  module P,
+  (!!),
+  fst,
+  snd,
+) where
+
+import Control.Lens as P hiding ((.>), (<.), (<.>))
+import Control.Lens.Extras as P
+
+import Papa.Lens.Data.List
+import Papa.Lens.Data.Tuple
diff --git a/src/Papa/Lens/Data/List.hs b/src/Papa/Lens/Data/List.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Lens/Data/List.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+{- HLINT ignore "Avoid restricted function" -}
+
+module Papa.Lens.Data.List (
+  (!!),
+) where
+
+import Control.Lens (Index, IxValue, Ixed, ix, (^?))
+import Data.Int (Int)
+import Data.Maybe (Maybe)
+
+-- | Safe list indexing. Returns 'Nothing' if the index is out of bounds.
+--
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> [1,2,3,4] !! 0
+-- Just 1
+-- >>> [1,2,3,4] !! 2
+-- Just 3
+-- >>> [1,2,3,4] !! 10
+-- Nothing
+{-# INLINE (!!) #-}
+{-# SPECIALIZE (!!) ::
+  [a] ->
+  Int ->
+  Maybe a
+  #-}
+(!!) ::
+  (Ixed s) =>
+  s ->
+  Index s ->
+  Maybe (IxValue s)
+q !! n =
+  q ^? ix n
+
+infixl 9 !!
diff --git a/src/Papa/Lens/Data/Tuple.hs b/src/Papa/Lens/Data/Tuple.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Lens/Data/Tuple.hs
@@ -0,0 +1,45 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Lens.Data.Tuple (
+  fst,
+  snd,
+) where
+
+import Control.Lens (Field1, Field2, (^.), _1, _2)
+
+-- | Extract the first component of a pair.
+--
+-- >>> fst (1, 2)
+-- 1
+-- >>> fst ('a', "hello")
+-- 'a'
+{-# INLINE fst #-}
+{-# SPECIALIZE fst ::
+  (a, b) ->
+  a
+  #-}
+fst ::
+  (Field1 s s b b) =>
+  s ->
+  b
+fst =
+  (^. _1)
+
+-- | Extract the second component of a pair.
+--
+-- >>> snd (1, 2)
+-- 2
+-- >>> snd ('a', "hello")
+-- "hello"
+{-# INLINE snd #-}
+{-# SPECIALIZE snd ::
+  (a, b) ->
+  b
+  #-}
+snd ::
+  (Field2 s s b b) =>
+  s ->
+  b
+snd =
+  (^. _2)
diff --git a/src/Papa/One.hs b/src/Papa/One.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/One.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.One (
+  module Papa.One.Control.One,
+) where
+
+import Papa.One.Control.One
diff --git a/src/Papa/One/Control/One.hs b/src/Papa/One/Control/One.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/One/Control/One.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.One.Control.One (
+  module X,
+) where
+
+import Control.One as X
diff --git a/src/Papa/One/Renamed.hs b/src/Papa/One/Renamed.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/One/Renamed.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | Re-exports from Papa.One with conflicting identifiers hidden.
+--
+-- The 'nonEmpty' function from Control.One.One conflicts with Data.List.NonEmpty.nonEmpty.
+-- It is hidden from this module. Use 'Control.One.One.nonEmpty' directly when needed,
+-- or import qualified:
+-- > import qualified Control.One.One as One
+module Papa.One.Renamed (
+  module Papa.One.Control.One,
+) where
+
+import Papa.One.Control.One hiding (nonEmpty)
diff --git a/src/Papa/Polytree.hs b/src/Papa/Polytree.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Polytree.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Polytree (
+  module Papa.Polytree.Data.Polytree,
+) where
+
+import Papa.Polytree.Data.Polytree
diff --git a/src/Papa/Polytree/Data/Polytree.hs b/src/Papa/Polytree/Data/Polytree.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Polytree/Data/Polytree.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Polytree.Data.Polytree (
+  module X,
+) where
+
+import Data.PolyTree as X
diff --git a/src/Papa/Polytree/Renamed.hs b/src/Papa/Polytree/Renamed.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Polytree/Renamed.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | Re-exports from Papa.Polytree with renamed conflicting identifiers.
+--
+-- This module provides alternative names for exports that conflict with Papa.Lens:
+-- - levels → treeLevels
+module Papa.Polytree.Renamed (
+  -- * Polytree re-exports without conflicts
+  module Papa.Polytree.Data.Polytree,
+
+  -- * Note on conflicts
+) where
+
+-- The 'levels' function from Data.PolyTree conflicts with Control.Lens.Level.levels
+-- Use 'Data.PolyTree.levels' directly when needed, or import qualified:
+-- > import qualified Data.PolyTree as Tree
+
+import Papa.Polytree.Data.Polytree hiding (levels)
diff --git a/src/Papa/Profunctors.hs b/src/Papa/Profunctors.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Profunctors.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Profunctors (
+  module Papa.Profunctors.Data.Profunctor,
+  module Papa.Profunctors.Data.Profunctor.Choice,
+  module Papa.Profunctors.Data.Profunctor.Strong,
+) where
+
+import Papa.Profunctors.Data.Profunctor
+import Papa.Profunctors.Data.Profunctor.Choice
+import Papa.Profunctors.Data.Profunctor.Strong
diff --git a/src/Papa/Profunctors/Data/Profunctor.hs b/src/Papa/Profunctors/Data/Profunctor.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Profunctors/Data/Profunctor.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Profunctors.Data.Profunctor (
+  module X,
+) where
+
+import Data.Profunctor as X
diff --git a/src/Papa/Profunctors/Data/Profunctor/Choice.hs b/src/Papa/Profunctors/Data/Profunctor/Choice.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Profunctors/Data/Profunctor/Choice.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Profunctors.Data.Profunctor.Choice (
+  module X,
+) where
+
+import Data.Profunctor.Choice as X
diff --git a/src/Papa/Profunctors/Data/Profunctor/Strong.hs b/src/Papa/Profunctors/Data/Profunctor/Strong.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Profunctors/Data/Profunctor/Strong.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Profunctors.Data.Profunctor.Strong (
+  module X,
+) where
+
+import Data.Profunctor.Strong as X
diff --git a/src/Papa/Profunctors/Renamed.hs b/src/Papa/Profunctors/Renamed.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Profunctors/Renamed.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | Re-exports from Papa.Profunctors with conflicting identifiers hidden.
+--
+-- The 'WrappedArrow' type from Data.Profunctor.Types conflicts with
+-- Control.Applicative.WrappedArrow. It is hidden from this module.
+-- Use 'Data.Profunctor.Types.WrappedArrow' directly when needed, or import qualified:
+-- > import qualified Data.Profunctor.Types as Prof
+module Papa.Profunctors.Renamed (
+  module Papa.Profunctors.Data.Profunctor,
+  module Papa.Profunctors.Data.Profunctor.Choice,
+  module Papa.Profunctors.Data.Profunctor.Strong,
+) where
+
+import Papa.Profunctors.Data.Profunctor hiding (WrappedArrow, unwrapArrow)
+import Papa.Profunctors.Data.Profunctor.Choice
+import Papa.Profunctors.Data.Profunctor.Strong
diff --git a/src/Papa/Selective.hs b/src/Papa/Selective.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Selective.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Selective (
+  module Papa.Selective.Control.Selective,
+) where
+
+import Papa.Selective.Control.Selective
diff --git a/src/Papa/Selective/Control/Selective.hs b/src/Papa/Selective/Control/Selective.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Selective/Control/Selective.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Selective.Control.Selective (
+  module X,
+) where
+
+import Control.Selective as X
diff --git a/src/Papa/Selective/Renamed.hs b/src/Papa/Selective/Renamed.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Selective/Renamed.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | Re-exports from Papa.Selective with conflicting identifiers hidden.
+--
+-- The 'Over' type from Control.Selective conflicts with Control.Lens.Type.Over.
+-- It is hidden from this module. Use 'Control.Selective.Over' directly when needed,
+-- or import qualified:
+-- > import qualified Control.Selective as Sel
+module Papa.Selective.Renamed (
+  module Papa.Selective.Control.Selective,
+) where
+
+import Papa.Selective.Control.Selective hiding (Over)
diff --git a/src/Papa/Semigroupoids.hs b/src/Papa/Semigroupoids.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Semigroupoids.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Semigroupoids (
+  module P,
+  concat,
+  concatMap,
+  maximum,
+  minimum,
+) where
+
+import Data.Bifunctor.Apply as P (Biapply ((.>>), (<<.), (<<.>>)), Bifunctor (bimap, first, second), bilift2, bilift3, (<<$>>), (<<..>>))
+import Data.Functor.Alt as P (Alt ((<!>)))
+import Data.Functor.Apply as P (Apply ((.>), (<.), (<.>)), MaybeApply (runMaybeApply), WrappedApplicative (unwrapApplicative), liftF2, liftF3, (<..>))
+import Data.Functor.Bind as P (Bind (join, (>>-)), apDefault, returning, (-<-), (-<<), (->-))
+import Data.Functor.Bind.Trans as P (BindTrans (liftB))
+import Data.Functor.Extend as P (Extend (duplicated, extended))
+import Data.Functor.Plus as P (Plus (zero))
+import Data.Groupoid as P (Groupoid (inv))
+import Data.Semigroup.Bifoldable as P (Bifoldable1 (bifold1, bifoldMap1), bifoldMapDefault1, bifor1_, bisequenceA1_, bitraverse1_)
+import Data.Semigroup.Bitraversable as P (Bitraversable1 (bisequence1, bitraverse1), bifoldMap1Default)
+import Data.Semigroup.Foldable as P (Foldable1 (fold1, foldMap1), asum1, foldMapDefault1, for1_, intercalate1, intercalateMap1, sequenceA1_, traverse1_)
+import Data.Semigroup.Traversable as P (Traversable1 (sequence1, traverse1), foldMap1Default)
+import Data.Semigroupoid as P (Semi (getSemi), Semigroupoid (o), WrappedCategory (unwrapCategory))
+import Data.Semigroupoid.Ob as P (Ob (semiid))
+import Data.Semigroupoid.Static as P (Static (runStatic))
+
+import Papa.Semigroupoids.Data.Functor.Bind
+import Papa.Semigroupoids.Data.Semigroup.Foldable
diff --git a/src/Papa/Semigroupoids/Data/Functor/Bind.hs b/src/Papa/Semigroupoids/Data/Functor/Bind.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Semigroupoids/Data/Functor/Bind.hs
@@ -0,0 +1,39 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Semigroupoids.Data.Functor.Bind (
+  concat,
+  concatMap,
+) where
+
+import Data.Functor.Bind (Bind (join), (-<<))
+
+{-# INLINE concat #-}
+
+-- | Flatten a nested structure.
+--
+-- >>> concat [[1,2], [3,4], [5,6]]
+-- [1,2,3,4,5,6]
+-- >>> import Data.Maybe (Maybe(..))
+-- >>> concat (Just (Just 5))
+-- Just 5
+concat ::
+  (Bind f) =>
+  f (f a) ->
+  f a
+concat =
+  join
+
+{-# INLINE concatMap #-}
+
+-- | Map a function over a structure and flatten.
+--
+-- >>> concatMap (\x -> [x, x]) [1,2,3]
+-- [1,1,2,2,3,3]
+concatMap ::
+  (Bind f) =>
+  (a -> f b) ->
+  f a ->
+  f b
+concatMap =
+  (-<<)
diff --git a/src/Papa/Semigroupoids/Data/Semigroup/Foldable.hs b/src/Papa/Semigroupoids/Data/Semigroup/Foldable.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Semigroupoids/Data/Semigroup/Foldable.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Semigroupoids.Data.Semigroup.Foldable (
+  maximum,
+  minimum,
+) where
+
+import Control.Category ((.))
+import Data.Ord (Ord)
+import Data.Semigroup (Max (Max, getMax), Min (Min, getMin))
+import Data.Semigroup.Foldable
+
+{-# INLINE maximum #-}
+
+-- | Find the maximum element in a non-empty structure.
+--
+-- >>> import Data.List.NonEmpty (NonEmpty(..))
+-- >>> maximum (1 :| [2,3,4])
+-- 4
+-- >>> maximum (10 :| [5,20,3])
+-- 20
+maximum ::
+  (Ord a, Foldable1 f) =>
+  f a ->
+  a
+maximum =
+  getMax . foldMap1 Max
+
+{-# INLINE minimum #-}
+
+-- | Find the minimum element in a non-empty structure.
+--
+-- >>> import Data.List.NonEmpty (NonEmpty(..))
+-- >>> minimum (1 :| [2,3,4])
+-- 1
+-- >>> minimum (10 :| [5,20,3])
+-- 3
+minimum ::
+  (Ord a, Foldable1 f) =>
+  f a ->
+  a
+minimum =
+  getMin . foldMap1 Min
diff --git a/src/Papa/Witherable.hs b/src/Papa/Witherable.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Witherable.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Witherable (
+  module Papa.Witherable.Witherable,
+) where
+
+import Papa.Witherable.Witherable
diff --git a/src/Papa/Witherable/Renamed.hs b/src/Papa/Witherable/Renamed.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Witherable/Renamed.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+-- | Re-exports from Papa.Witherable with conflicting identifiers hidden.
+--
+-- Conflicts hidden:
+-- - 'filter' (conflicts with Data.List.filter)
+-- - 'catMaybes' (conflicts with Data.Maybe.catMaybes)
+-- - 'mapMaybe' (conflicts with Data.Maybe.mapMaybe)
+--
+-- Use qualified imports when needed:
+-- > import qualified Witherable as W
+module Papa.Witherable.Renamed (
+  module Papa.Witherable.Witherable,
+) where
+
+import Papa.Witherable.Witherable hiding (catMaybes, filter, mapMaybe)
diff --git a/src/Papa/Witherable/Witherable.hs b/src/Papa/Witherable/Witherable.hs
new file mode 100644
--- /dev/null
+++ b/src/Papa/Witherable/Witherable.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module Papa.Witherable.Witherable (
+  module X,
+) where
+
+import Witherable as X
diff --git a/test/Doctest.hs b/test/Doctest.hs
new file mode 100644
--- /dev/null
+++ b/test/Doctest.hs
@@ -0,0 +1,18 @@
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
+
+module Main (main) where
+
+import System.Exit (exitWith)
+import System.Process (rawSystem)
+
+main :: IO ()
+main =
+  exitWith
+    =<< rawSystem
+      "cabal"
+      [ "repl"
+      , "--with-compiler=doctest"
+      , "--repl-options=-w"
+      , "--repl-options=-Wdefault"
+      , "lib:papa"
+      ]
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,50 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wall #-}
+
+{- HLINT ignore "Avoid restricted function" -}
+{- HLINT ignore "Evaluate" -}
+
+module Main where
+
+import Papa
+import System.Exit (exitFailure, exitSuccess)
+
+assert :: Bool -> String -> IO ()
+assert True _ = pure ()
+assert False msg = putStrLn ("FAIL: " ++ msg) *> exitFailure
+
+main :: IO ()
+main = do
+  -- Total (!!) using lens-based safe indexing
+  assert (is _Nothing (([] :: [Int]) !! (1 :: Int))) "[] !! 1 == Nothing"
+  assert ([10 :: Int, 20, 30] !! (1 :: Int) == Just 20) "[10,20,30] !! 1 == Just 20"
+
+  -- Generalized map (Functor)
+  assert (map (+ (1 :: Int)) [1, 2, 3] == [2, 3, 4]) "map (+1) [1,2,3] == [2,3,4]"
+
+  -- Generalized (++) (Semigroup)
+  assert ("abc" ++ "def" == "abcdef") "abc ++ def == abcdef"
+
+  -- Generalized lookup (Foldable)
+  assert (lookup 'b' [('a', 1 :: Int), ('b', 2)] == Just 2) "lookup 'b' == Just 2"
+  assert (is _Nothing (lookup 'z' [('a', 1 :: Int)])) "lookup 'z' == Nothing"
+
+  -- fst/snd via lens (Field1/Field2)
+  assert (fst (1 :: Int, 'a') == 1) "fst (1, 'a') == 1"
+  assert (snd (1 :: Int, 'a') == 'a') "snd (1, 'a') == 'a'"
+
+  -- mconcat (Foldable Monoid)
+  assert (mconcat ["a", "b", "c"] == "abc") "mconcat [a,b,c] == abc"
+
+  -- maximum/minimum (Foldable1)
+  assert (maximum (1 :| [2, 3 :: Int]) == 3) "maximum (1 :| [2,3]) == 3"
+  assert (minimum (1 :| [2, 3 :: Int]) == 1) "minimum (1 :| [2,3]) == 1"
+
+  -- const (Applicative pure)
+  assert ((const 42 :: Maybe Int) == Just 42) "const 42 == Just 42"
+
+  -- Const constructor accessible (issue 6)
+  assert (getConst (Const "hello" :: Const String Int) == "hello") "Const constructor"
+
+  putStrLn "All tests passed."
+  exitSuccess
