diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,26 @@
 Changelog
 =========
 
+Version 0.3.1.0
+---------------
+
+*August 7, 2020*
+
+<https://github.com/mstksg/functor-combinators/releases/tag/v0.3.1.0>
+
+*   *Data.HFunctor.Interpret*: `getI` and `collectI` made more efficient, and
+    renamed to `iget` and `icollect`, respectively, to mirror `biget` and
+    `bicollect`.  `getI` and `collectI` are left in with a deprecation warning.
+    `icollect1` added to ensure a non-empty collection.  `AltConst` added to
+    aid in implementation.
+*   *Data.HBifunctor.Associative*: `bicollect1` added to ensure a non-empty
+    collection.  *biget* and *bicollect* made more efficient.
+*   *Data.Functor.Contravariant.Night*, *Data.Functor.Invariant.Night*:
+    `refuted` added for a convenient `Not`.  Missing `Invariant` instance for
+    `Not` also added.
+*   *Data.HFunctor.Chain*: `chainPair` and `chain1Pair` renamed to `toChain`
+    and `toChain1`, respectively, to mirror `toListBy` and `toNonEmptyBy`.
+
 Version 0.3.0.0
 ---------------
 
diff --git a/functor-combinators.cabal b/functor-combinators.cabal
--- a/functor-combinators.cabal
+++ b/functor-combinators.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: f15c50b5510d900bedb796a057cf16600ffce2bd338dba4daa4015f54400bc18
+-- hash: 1a0532f73e7e38dc05fe8b07be016e7013f4f32c9daebe758f093a8abd0f4a45
 
 name:           functor-combinators
-version:        0.3.0.0
+version:        0.3.1.0
 synopsis:       Tools for functor combinator-based program design
 description:    Tools for working with /functor combinators/: types that take functors (or
                 other indexed types) and returns a new functor that "enhances" or "mixes"
@@ -83,6 +83,7 @@
     , containers
     , contravariant
     , deriving-compat
+    , dlist >=1.0
     , free
     , invariant
     , kan-extensions
diff --git a/src/Data/Functor/Combinator.hs b/src/Data/Functor/Combinator.hs
--- a/src/Data/Functor/Combinator.hs
+++ b/src/Data/Functor/Combinator.hs
@@ -43,8 +43,9 @@
   , Inject(..)
   , Interpret(..)
   , forI
-  , getI
-  , collectI
+  , iget, icollect, icollect1
+  , getI, collectI
+  , AltConst(..)
   -- ** Multi-Functors
   -- | Classes that deal with two-functor combinators, that "mix" two
   -- functors together in some way.
@@ -52,7 +53,7 @@
   -- *** Associative
   , Associative(..)
   , SemigroupIn(..)
-  , biget, bicollect
+  , biget, bicollect, bicollect1
   , (!*!)
   , (!+!)
   , (!$!)
@@ -94,6 +95,7 @@
   , (:*:)(..), prodOutL, prodOutR
   , (:+:)(..), V1
   , These1(..)
+  , Night(..), Not(..), refuted
   , Comp(Comp, unComp)
   , LeftF(..)
   , RightF(..)
@@ -127,12 +129,13 @@
 import           Control.Natural.IsoF
 import           Data.Functor.Apply.Free
 import           Data.Functor.Contravariant
-import           Data.Functor.Contravariant.Decide
 import           Data.Functor.Contravariant.Conclude
+import           Data.Functor.Contravariant.Decide
 import           Data.Functor.Contravariant.Divise
 import           Data.Functor.Contravariant.Divisible
 import           Data.Functor.Coyoneda
 import           Data.Functor.Day
+import           Data.Functor.Invariant.Night
 import           Data.Functor.These
 import           Data.HBifunctor
 import           Data.HBifunctor.Associative
@@ -171,6 +174,14 @@
 --          :* Nil
 -- @
 --
+-- Some notes on usefulness depending on how many components you have:
+--
+-- *    If you have 0 components, use 'conquer'.
+-- *    If you have 1 component, use 'inject' directly.
+-- *    If you have 2 components, use 'divide' directly.
+-- *    If you have 3 or more components, these combinators may be useful;
+--      otherwise you'd need to manually peel off tuples one-by-one.
+--
 -- @since 0.3.0.0
 divideN
     :: Divisible f
@@ -263,6 +274,14 @@
 --            :* stringBuilder
 --            :* Nil
 -- @
+--
+-- Some notes on usefulness depending on how many components you have:
+--
+-- *    If you have 0 components, use 'conclude'.
+-- *    If you have 1 component, use 'inject' directly.
+-- *    If you have 2 components, use 'decide' directly.
+-- *    If you have 3 or more components, these combinators may be useful;
+--      otherwise you'd need to manually peel off eithers one-by-one.
 --
 -- @since 0.3.0.0
 concludeN
diff --git a/src/Data/Functor/Contravariant/Conclude.hs b/src/Data/Functor/Contravariant/Conclude.hs
--- a/src/Data/Functor/Contravariant/Conclude.hs
+++ b/src/Data/Functor/Contravariant/Conclude.hs
@@ -67,9 +67,10 @@
 import GHC.Generics
 #endif
 
--- | The contravariant analogue of 'Plus'.  Adds on to 'Decide' the ability
--- to express a combinator that rejects all input, to act as the dead-end.
--- Essentially 'Decidable' without a superclass constraint on 'Divisible'.
+-- | The contravariant analogue of 'Data.Functor.Plus.Plus'.  Adds on to
+-- 'Decide' the ability to express a combinator that rejects all input, to
+-- act as the dead-end. Essentially 'Decidable' without a superclass
+-- constraint on 'Divisible'.
 --
 -- If one thinks of @f a@ as a consumer of @a@s, then 'conclude' defines
 -- a consumer that cannot ever receive /any/ input.
diff --git a/src/Data/Functor/Contravariant/Night.hs b/src/Data/Functor/Contravariant/Night.hs
--- a/src/Data/Functor/Contravariant/Night.hs
+++ b/src/Data/Functor/Contravariant/Night.hs
@@ -21,7 +21,7 @@
   , trans1, trans2
   , intro1, intro2
   , elim1, elim2
-  , Not(..)
+  , Not(..), refuted
   ) where
 
 import           Control.Natural
@@ -105,8 +105,17 @@
 -- | A value of type @'Not' a@ is "proof" that @a@ is uninhabited.
 newtype Not a = Not { refute :: a -> Void }
 
+-- | A useful shortcut for a common usage: 'Void' is always not so.
+--
+-- @since 0.3.1.0
+refuted :: Not Void
+refuted = Not id
+
 instance Contravariant Not where
     contramap f (Not g) = Not (g . f)
+-- | @since 0.3.1.0
+instance Invariant Not where
+    invmap _ = contramap
 
 instance Semigroup (Not a) where
     Not f <> Not g = Not (f <> g)
@@ -114,12 +123,12 @@
 -- | The left identity of 'Night' is 'Not'; this is one side of that
 -- isomorphism.
 intro1 :: g ~> Night Not g
-intro1 x = Night (Not id) x Right
+intro1 x = Night refuted x Right
 
 -- | The right identity of 'Night' is 'Not'; this is one side of that
 -- isomorphism.
 intro2 :: f ~> Night f Not
-intro2 x = Night x (Not id) Left
+intro2 x = Night x refuted Left
 
 -- | The left identity of 'Night' is 'Not'; this is one side of that
 -- isomorphism.
diff --git a/src/Data/Functor/Invariant/Day.hs b/src/Data/Functor/Invariant/Day.hs
--- a/src/Data/Functor/Invariant/Day.hs
+++ b/src/Data/Functor/Invariant/Day.hs
@@ -275,7 +275,7 @@
     matchNE = matchChain1
 
     consNE = More1
-    toNonEmptyBy = More1 . hright Done1
+    toNonEmptyBy = toChain1
 
 instance Tensor Day Identity where
     type ListBy Day = DayChain
@@ -289,7 +289,7 @@
     splitNE = splitChain1
     splittingLB = splittingChain
 
-    toListBy = More . hright inject
+    toListBy = toChain
 
 instance Matchable Day Identity where
     unsplitNE (Day x xs f g) = case xs of
@@ -323,9 +323,13 @@
 --                   :* Nil
 -- @
 --
--- This is much more convenient than doing it using manual applications of
--- 'divide' or 'divise' or 'Day', which would require manually peeling off
--- tuples one-by-one.
+-- Some notes on usefulness depending on how many components you have:
+--
+-- *    If you have 0 components, use 'Knot' directly.
+-- *    If you have 1 component, use 'inject' or 'injectChain' directly.
+-- *    If you have 2 components, use 'toListBy' or 'toChain'.
+-- *    If you have 3 or more components, these combinators may be useful;
+--      otherwise you'd need to manually peel off tuples one-by-one.
 assembleDayChain
     :: NP f as
     -> DayChain f (NP I as)
diff --git a/src/Data/Functor/Invariant/Night.hs b/src/Data/Functor/Invariant/Night.hs
--- a/src/Data/Functor/Invariant/Night.hs
+++ b/src/Data/Functor/Invariant/Night.hs
@@ -13,7 +13,7 @@
 -- @since 0.3.0.0
 module Data.Functor.Invariant.Night (
     Night(..)
-  , Not(..)
+  , Not(..), refuted
   , night
   , runNightAlt
   , runNightDecide
@@ -46,7 +46,7 @@
 import           Data.Functor.Alt
 import           Data.Functor.Contravariant.Conclude
 import           Data.Functor.Contravariant.Decide
-import           Data.Functor.Contravariant.Night    (Not(..))
+import           Data.Functor.Contravariant.Night    (Not(..), refuted)
 import           Data.Functor.Invariant
 import           Data.Functor.Plus
 import           Data.HBifunctor
@@ -149,12 +149,12 @@
 -- | The left identity of 'Night' is 'Not'; this is one side of that
 -- isomorphism.
 intro1 :: g ~> Night Not g
-intro1 y = Night (Not id) y Right absurd id
+intro1 y = Night refuted y Right absurd id
 
 -- | The right identity of 'Night' is 'Not'; this is one side of that
 -- isomorphism.
 intro2 :: f ~> Night f Not
-intro2 x = Night x (Not id) Left id absurd
+intro2 x = Night x refuted Left id absurd
 
 -- | The left identity of 'Night' is 'Not'; this is one side of that
 -- isomorphism.
@@ -282,7 +282,7 @@
     matchNE = matchChain1
 
     consNE = More1
-    toNonEmptyBy = chain1Pair
+    toNonEmptyBy = toChain1
 
 instance Tensor Night Not where
     type ListBy Night = NightChain
@@ -296,7 +296,7 @@
     splitNE = splitChain1
     splittingLB = splittingChain
 
-    toListBy = chainPair
+    toListBy = toChain
 
 instance Matchable Night Not where
     unsplitNE (Night x xs f g h) = case xs of
@@ -330,9 +330,13 @@
 --                     :* Nil
 -- @
 --
--- This is much more convenient than doing it using manual applications of
--- 'decide' or 'Data.Functor.Contravariant.Divisible.choose' or 'Night',
--- which would require manually peeling off eithers one-by-one.
+-- Some notes on usefulness depending on how many components you have:
+--
+-- *    If you have 0 components, use 'Reject' directly.
+-- *    If you have 1 component, use 'inject' or 'injectChain' directly.
+-- *    If you have 2 components, use 'toListBy' or 'toChain'.
+-- *    If you have 3 or more components, these combinators may be useful;
+--      otherwise you'd need to manually peel off eithers one-by-one.
 assembleNightChain
     :: NP f as
     -> NightChain f (NS I as)
@@ -385,7 +389,8 @@
 
 -- | A version of 'concatNightChain' but for 'NightChain1' instead.  Can be
 -- useful if you intend on interpreting it into something with only
--- a 'Decide' or 'Alt' instance, but no 'Decidable' or 'Plus' or
+-- a 'Decide' or 'Alt' instance, but no
+-- 'Data.Functor.Contravariant.Divisible.Decidable' or 'Plus' or
 -- 'Control.Applicative.Alternative'.
 concatNightChain1
     :: Invariant f
diff --git a/src/Data/HBifunctor/Associative.hs b/src/Data/HBifunctor/Associative.hs
--- a/src/Data/HBifunctor/Associative.hs
+++ b/src/Data/HBifunctor/Associative.hs
@@ -45,6 +45,7 @@
   -- ** Utility
   , biget
   , bicollect
+  , bicollect1
   , (!*!)
   , (!$!)
   , (!+!)
@@ -52,7 +53,6 @@
   , WrapNE(..)
   ) where
 
-import           Control.Applicative
 import           Control.Applicative.ListF
 import           Control.Applicative.Step
 import           Control.Monad.Freer.Church
@@ -88,6 +88,8 @@
 import           Data.List.NonEmpty                        (NonEmpty(..))
 import           Data.Void
 import           GHC.Generics
+import qualified Data.DList                                as DL
+import qualified Data.DList.DNonEmpty                      as NEDL
 import qualified Data.Functor.Contravariant.Day            as CD
 import qualified Data.Functor.Contravariant.Night          as N
 import qualified Data.Functor.Day                          as D
@@ -307,8 +309,11 @@
 -- you may have extra constraints on @b@.
 --
 -- *    If @f@ is unconstrained, there are no constraints on @b@
--- *    If @f@ must be 'Apply', @b@ needs to be an instance of 'Semigroup'
--- *    If @f@ must be 'Applicative', @b@ needs to be an instance of 'Monoid'
+-- *    If @f@ must be 'Apply', 'Alt', 'Divise', or 'Decide', @b@ needs to be an instance of 'Semigroup'
+-- *    If @f@ is 'Applicative', 'Plus',
+--      'Data.Functor.Contravariant.Divisible.Divisible', or
+--      'Data.Functor.Contravariant.Conclude.Conclude', @b@ needs to be an
+--      instance of 'Monoid'
 --
 -- For some constraints (like 'Monad'), this will not be usable.
 --
@@ -325,12 +330,12 @@
 --     -> Sum Int
 -- @
 biget
-    :: SemigroupIn t (Const b)
+    :: SemigroupIn t (AltConst b)
     => (forall x. f x -> b)
     -> (forall x. g x -> b)
     -> t f g a
     -> b
-biget f g = getConst . binterpret (Const . f) (Const . g)
+biget f g = getAltConst . binterpret (AltConst . f) (AltConst . g)
 
 -- | Infix alias for 'biget'
 --
@@ -347,7 +352,7 @@
 --     -> Sum Int
 -- @
 (!$!)
-    :: SemigroupIn t (Const b)
+    :: SemigroupIn t (AltConst b)
     => (forall x. f x -> b)
     -> (forall x. g x -> b)
     -> t f g a
@@ -386,14 +391,33 @@
 -- instances of @f@ and @g@ inside a @t f g a@.
 --
 -- This will work if the constraint on @f@ for @'SemigroupIn' t f@ is
--- 'Apply' or 'Applicative', or if it is unconstrained.
+-- 'Apply', 'Applicative', 'Alt', 'Plus', 'Divise',
+-- 'Data.Functor.Contravariant.Divisible.Divisible', 'Decide',
+-- 'Data.Functor.Contravariant.Conclude.Conclude', or if it is unconstrained.
 bicollect
-    :: SemigroupIn t (Const [b])
+    :: SemigroupIn t (AltConst (DL.DList b))
     => (forall x. f x -> b)
     -> (forall x. g x -> b)
     -> t f g a
     -> [b]
-bicollect f g = biget ((:[]) . f) ((:[]) . g)
+bicollect f g = toList . biget (DL.singleton . f) (DL.singleton . g)
+
+-- | Useful wrapper over 'biget' to allow you to collect a @b@ from all
+-- instances of @f@ and @g@ inside a @t f g a@ into a non-empty collection
+-- of @b@s.
+--
+-- This will work if the constraint on @f@ for @'SemigroupIn' t f@ is
+-- 'Apply', 'Alt', 'Divise', 'Decide', or if it is unconstrained.
+--
+-- @since 0.3.1.0
+bicollect1
+    :: SemigroupIn t (AltConst (NEDL.DNonEmpty b))
+    => (forall x. f x -> b)
+    -> (forall x. g x -> b)
+    -> t f g a
+    -> NonEmpty b
+bicollect1 f g = NEDL.toNonEmpty . biget (NEDL.singleton . f) (NEDL.singleton . g)
+
 
 instance Associative (:*:) where
     type NonEmptyBy (:*:) = NonEmptyF
diff --git a/src/Data/HBifunctor/Tensor.hs b/src/Data/HBifunctor/Tensor.hs
--- a/src/Data/HBifunctor/Tensor.hs
+++ b/src/Data/HBifunctor/Tensor.hs
@@ -256,13 +256,11 @@
 prodRightIdentity :: g <~> g :*: Proxy
 prodRightIdentity = isoF (:*: Proxy) (\case x :*: _ -> x)
 
--- | 'outL' for ':*:' actually does not require 'Functor'.  This is the
--- more general version.
+-- | A poly-kinded version of 'outL' for ':*:'.
 prodOutL :: f :*: g ~> f
 prodOutL (x :*: _) = x
 
--- | 'outR' for ':*:' actually does not require 'Functor'.  This is the
--- more general version.
+-- | A poly-kinded version of 'outR' for ':*:'.
 prodOutR :: f :*: g ~> g
 prodOutR (_ :*: y) = y
 
diff --git a/src/Data/HFunctor/Chain.hs b/src/Data/HFunctor/Chain.hs
--- a/src/Data/HFunctor/Chain.hs
+++ b/src/Data/HFunctor/Chain.hs
@@ -32,7 +32,7 @@
   , unrolling
   , appendChain
   , splittingChain
-  , chainPair
+  , toChain
   , injectChain
   , unconsChain
   -- * 'Chain1'
@@ -45,7 +45,7 @@
   , appendChain1
   , fromChain1
   , matchChain1
-  , chain1Pair
+  , toChain1
   , injectChain1
   -- ** Matchable
   -- | The following conversions between 'Chain' and 'Chain1' are only
@@ -240,11 +240,12 @@
           Done1 x  -> f x
           More1 xs -> binterpret f go xs
 
--- | Convert a tensor value pairing two @f@s into a two-item chain.
+-- | Convert a tensor value pairing two @f@s into a two-item 'Chain1'.  An
+-- analogue of 'toNonEmptyBy'.
 --
--- @since 0.3.0.0
-chain1Pair :: HBifunctor t => t f f ~> Chain1 t f
-chain1Pair = More1 . hright Done1
+-- @since 0.3.1.0
+toChain1 :: HBifunctor t => t f f ~> Chain1 t f
+toChain1 = More1 . hright Done1
 
 -- | Create a singleton 'Chain1'.
 --
@@ -486,13 +487,14 @@
           Done x  -> pureT @t x
           More xs -> binterpret f go xs
 
--- | Convert a tensor value pairing two @f@s into a two-item chain.
+-- | Convert a tensor value pairing two @f@s into a two-item 'Chain'.  An
+-- analogue of 'toListBy'.
 --
--- @since 0.3.0.0
-chainPair :: Tensor t i => t f f ~> Chain t i f
-chainPair = More . hright inject
+-- @since 0.3.1.0
+toChain :: Tensor t i => t f f ~> Chain t i f
+toChain = More . hright inject
 
--- | Create a singleton chain
+-- | Create a singleton chain.
 --
 -- @since 0.3.0.0
 injectChain :: Tensor t i => f ~> Chain t i f
diff --git a/src/Data/HFunctor/Interpret.hs b/src/Data/HFunctor/Interpret.hs
--- a/src/Data/HFunctor/Interpret.hs
+++ b/src/Data/HFunctor/Interpret.hs
@@ -43,8 +43,11 @@
 module Data.HFunctor.Interpret (
     Interpret(..), forI
   -- * Utilities
-  , getI
-  , collectI
+  , iget
+  , icollect
+  , icollect1
+  , getI, collectI
+  , AltConst(..)
   , AndC
   , WrapHF(..)
   ) where
@@ -54,7 +57,7 @@
 import           Control.Applicative.Lift
 import           Control.Applicative.ListF
 import           Control.Applicative.Step
-import           Control.Comonad.Trans.Env           (EnvT(..))
+import           Control.Comonad.Trans.Env            (EnvT(..))
 import           Control.Monad.Freer.Church
 import           Control.Monad.Reader
 import           Control.Monad.Trans.Compose
@@ -62,26 +65,35 @@
 import           Control.Natural
 import           Data.Coerce
 import           Data.Data
+import           Data.Foldable
 import           Data.Functor.Bind
 import           Data.Functor.Classes
 import           Data.Functor.Contravariant
+import           Data.Functor.Contravariant.Conclude
+import           Data.Functor.Contravariant.Decide
+import           Data.Functor.Contravariant.Divise
+import           Data.Functor.Contravariant.Divisible
 import           Data.Functor.Coyoneda
+import           Data.Functor.Invariant
 import           Data.Functor.Plus
 import           Data.Functor.Product
 import           Data.Functor.Reverse
 import           Data.Functor.Sum
 import           Data.Functor.These
 import           Data.HFunctor
+import           Data.List.NonEmpty                   (NonEmpty(..))
 import           Data.Maybe
 import           Data.Pointed
 import           Data.Semigroup.Foldable
 import           GHC.Generics
-import qualified Control.Alternative.Free            as Alt
-import qualified Control.Applicative.Free            as Ap
-import qualified Control.Applicative.Free.Fast       as FAF
-import qualified Control.Applicative.Free.Final      as FA
-import qualified Data.Functor.Contravariant.Coyoneda as CCY
-import qualified Data.Map.NonEmpty                   as NEM
+import qualified Control.Alternative.Free             as Alt
+import qualified Control.Applicative.Free             as Ap
+import qualified Control.Applicative.Free.Fast        as FAF
+import qualified Control.Applicative.Free.Final       as FA
+import qualified Data.DList                           as DL
+import qualified Data.DList.DNonEmpty                 as NEDL
+import qualified Data.Functor.Contravariant.Coyoneda  as CCY
+import qualified Data.Map.NonEmpty                    as NEM
 
 -- | An 'Interpret' lets us move in and out of the "enhanced" 'Functor' (@t
 -- f@) and the functor it enhances (@f@).  An instance @'Interpret' t f@
@@ -157,43 +169,135 @@
 -- may have extra constraints on @b@.
 --
 -- *    If @f@ is unconstrained, there are no constraints on @b@
--- *    If @f@ must be 'Apply', @b@ needs to be an instance of 'Semigroup'
--- *    If @f@ is 'Applicative', @b@ needs to be an instance of 'Monoid'
+-- *    If @f@ must be 'Apply', 'Alt', 'Divise', or 'Decide', @b@ needs to be an instance of 'Semigroup'
+-- *    If @f@ is 'Applicative', 'Plus', 'Divisible', or 'Conclude', @b@ needs to be an instance of 'Monoid'
 --
 -- For some constraints (like 'Monad'), this will not be usable.
 --
 -- @
 -- -- get the length of the @Map String@ in the 'Step'.
--- 'collectI' length
+-- 'icollect' length
 --      :: Step (Map String) Bool
 --      -> Int
 -- @
-getI
-    :: Interpret t (Const b)
+--
+-- @since 0.3.1.0
+iget
+    :: Interpret t (AltConst b)
     => (forall x. f x -> b)
     -> t f a
     -> b
-getI f = getConst . interpret (Const . f)
+iget f = getAltConst . interpret (AltConst . f)
 
--- | Useful wrapper over 'getI' to allow you to collect a @b@ from all
+-- | (Deprecated) Old name for 'getI'; will be removed in a future
+-- version.
+getI :: Interpret t (AltConst b) => (forall x. f x -> b) -> t f a -> b
+getI = iget
+{-# DEPRECATED getI "Use iget instead" #-}
+
+-- | Useful wrapper over 'iget' to allow you to collect a @b@ from all
 -- instances of @f@ inside a @t f a@.
 --
--- Will work if there is an instance of @'Interpret' t ('Const' [b])@,
--- which will be the case if the constraint on the target functor is
--- 'Functor', 'Apply', 'Applicative', or unconstrianed.
+-- Will work if there is an instance of @'Interpret' t ('AltConst'
+-- ('DL.DList' b))@, which will be the case if the constraint on the target
+-- functor is 'Functor', 'Apply', 'Applicative', 'Alt', 'Plus',
+-- 'Data.Functor.Contravariant.Decide.Decide', 'Divisible', 'Decide',
+-- 'Conclude', or unconstrained.
 --
 -- @
 -- -- get the lengths of all @Map String@s in the 'Ap.Ap'.
--- 'collectI' length
+-- 'icollect' length
 --      :: Ap (Map String) Bool
 --      -> [Int]
 -- @
-collectI
-    :: Interpret t (Const [b])
+--
+-- @since 0.3.1.0
+icollect
+    :: Interpret t (AltConst (DL.DList b))
     => (forall x. f x -> b)
     -> t f a
     -> [b]
-collectI f = getI ((:[]) . f)
+icollect f = toList . iget (DL.singleton . f)
+
+-- | (Deprecated) Old name for 'icollect'; will be removed in a future
+-- version.
+collectI :: Interpret t (AltConst (DL.DList b)) => (forall x. f x -> b) -> t f a -> [b]
+collectI = icollect
+{-# DEPRECATED collectI "Use icollect instead" #-}
+
+-- | Useful wrapper over 'iget' to allow you to collect a @b@ from all
+-- instances of @f@ inside a @t f a@, into a non-empty collection of @b@s.
+--
+-- Will work if there is an instance of @'Interpret' t ('AltConst'
+-- ('NEDL.DNonEmpty' b))@, which will be the case if the constraint on the
+-- target functor is 'Functor', 'Apply', 'Alt', 'Divise', 'Decide', or
+-- unconstrained.
+--
+-- @
+-- -- get the lengths of all @Map String@s in the 'Ap.Ap'.
+-- 'icollect1' length
+--      :: Ap1 (Map String) Bool
+--      -> 'NonEmpty' Int
+-- @
+--
+-- @since 0.3.1.0
+icollect1
+    :: Interpret t (AltConst (NEDL.DNonEmpty b))
+    => (forall x. f x -> b)
+    -> t f a
+    -> NonEmpty b
+icollect1 f = NEDL.toNonEmpty . iget (NEDL.singleton . f)
+
+-- | A version of 'Const' that supports 'Alt', 'Plus', 'Decide', and
+-- 'Conclude' instances.  It does this
+-- by avoiding having an 'Alternative' or 'Decidable' instance, which
+-- causes all sorts of problems with the interactions between
+-- 'Alternative'/'Applicative' and
+-- 'Decidable'/'Data.Functor.Contravariant.Divisible.Divisible'.
+--
+-- @since 0.3.1.0
+newtype AltConst w a = AltConst { getAltConst :: w }
+  deriving (Show, Eq, Ord, Generic, Functor, Foldable, Traversable, Data)
+
+instance Show w => Show1 (AltConst w) where
+    liftShowsPrec _ _ d (AltConst x) = showsUnaryWith showsPrec "AltConst" d x
+instance Eq w => Eq1 (AltConst w) where
+    liftEq _ (AltConst x) (AltConst y) = x == y
+instance Ord w => Ord1 (AltConst w) where
+    liftCompare _ (AltConst x) (AltConst y) = compare x y
+
+instance Contravariant (AltConst w) where
+    contramap _ = coerce
+instance Invariant (AltConst w) where
+    invmap _ _ = coerce
+
+instance Semigroup w => Apply (AltConst w) where
+    AltConst x <.> AltConst y = AltConst (x <> y)
+instance Monoid w => Applicative (AltConst w) where
+    (<*>) = (<.>)
+    pure _ = AltConst mempty
+-- | Unlike for 'Const', this is possible because there is no 'Alternative'
+-- instance to complicate things.
+instance Semigroup w => Alt (AltConst w) where
+    AltConst x <!> AltConst y = AltConst (x <> y)
+-- | Unlike for 'Const', this is possible because there is no 'Alternative'
+-- instance to complicate things.
+instance Monoid w => Plus (AltConst w) where
+    zero = AltConst mempty
+
+instance Semigroup w => Divise (AltConst w) where
+    divise _ (AltConst x) (AltConst y) = AltConst (x <> y)
+instance Monoid w => Divisible (AltConst w) where
+    divide  = divise
+    conquer = AltConst mempty
+-- | Unlike for 'Const', this is possible because there is no 'Decidable'
+-- instance to complicate things.
+instance Semigroup w => Decide (AltConst w) where
+    decide _ (AltConst x) (AltConst y) = AltConst (x <> y)
+-- | Unlike for 'Const', this is possible because there is no 'Decidable'
+-- instance to complicate things.
+instance Monoid w => Conclude (AltConst w) where
+    conclude _ = AltConst mempty
 
 -- | A free 'Functor'
 instance Functor f => Interpret Coyoneda f where
diff --git a/test/Tests/Util.hs b/test/Tests/Util.hs
--- a/test/Tests/Util.hs
+++ b/test/Tests/Util.hs
@@ -29,6 +29,7 @@
 import           Data.GADT.Show
 import           Data.HBifunctor.Tensor
 import           Data.HFunctor.Chain
+import           Data.HFunctor.Interpret
 import           Data.Kind
 import           Data.Semigroup                 (Any(..))
 import           Data.Semigroup.Traversable
@@ -250,9 +251,6 @@
 
 instance (Enum e, Bounded e) => TestHFunctor (EnvT e) where
     genHF gx = EnvT <$> Gen.enumBounded <*> gx
-
-class (c f, d f) => AndC c d f
-instance (c f, d f) => AndC c d f
 
 instance (TestHFunctor s, HTraversable s, TestHFunctor t) => TestHFunctor (ComposeT s t) where
     type TestHFunctorBy (ComposeT s t) = AndC (TestHFunctorBy s) (TestHFunctorBy t)
