diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+0.5
+---
+
+* `FilterableWithIndex` is a superclass of `WitherableWithIndex`.
+* Remove deprecated `Data.Witherable` module. Use `Witherable` module.
+* Relax `FilterableWithIndex` composition law so list-like instances are lawful.
+* Add `drain :: f a -> f b` method (with default implementation `drain = mapMaybe (Const Nothing)`) to the `Filterable`.
+
 0.4.2
 -------
 
diff --git a/src/Data/Witherable.hs b/src/Data/Witherable.hs
deleted file mode 100644
--- a/src/Data/Witherable.hs
+++ /dev/null
@@ -1,163 +0,0 @@
-{-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE Trustworthy #-}
------------------------------------------------------------------------------
--- |
--- Module      :  Data.Witherable
--- Copyright   :  (c) Fumiaki Kinoshita 2015
--- License     :  BSD3
---
--- Maintainer  :  Fumiaki Kinoshita <fumiexcel@gmail.com>
--- Stability   :  provisional
--- Portability :  non-portable
---
------------------------------------------------------------------------------
-module Data.Witherable {-# DEPRECATED "Use Witherable instead" #-}
-  ( Filterable(..)
-  , (<$?>)
-  , (<&?>)
-  , Witherable(..)
-  , ordNub
-  , ordNubOn
-  , hashNub
-  , hashNubOn
-  , forMaybe
-  -- * Indexed variants
-  , FilterableWithIndex(..)
-  , WitherableWithIndex(..)
-  -- * Generalization
-  , WitherLike, Wither, WitherLike', Wither'
-  , FilterLike, Filter, FilterLike', Filter'
-  , witherOf
-  , forMaybeOf
-  , mapMaybeOf
-  , catMaybesOf
-  , filterAOf
-  , filterOf
-  , ordNubOf
-  , ordNubOnOf
-  , hashNubOf
-  , hashNubOnOf
-   -- * Cloning
-  , cloneFilter
-  , Peat(..)
-  -- * Wrapper
-  , WrappedFoldable(..)
-  ) where
-
-import Control.Applicative
-import Data.Functor.Identity
-import Witherable
-import qualified Data.Set as Set
-import qualified Data.HashSet as HSet
-import Control.Monad.Trans.State.Strict
-import Data.Hashable
-import Data.Coerce
-
-type Filter s t a b = Wither s t a b
-{-# DEPRECATED Filter "Use Wither instead" #-}
-type FilterLike f s t a b = WitherLike f s t a b
-{-# DEPRECATED FilterLike "Use WitherLike instead" #-}
-type Filter' s a = Wither' s a
-{-# DEPRECATED Filter' "Use Filter' instead" #-}
-type FilterLike' f s a = WitherLike' f s a
-{-# DEPRECATED FilterLike' "Use WitherLike' instead" #-}
-
--- | This type allows combinators to take a 'Filter' specializing the parameter @f@.
-type WitherLike f s t a b = (a -> f (Maybe b)) -> s -> f t
-
--- | A 'Wither' is like a <http://hackage.haskell.org/package/lens-4.13.2.1/docs/Control-Lens-Type.html#t:Traversal Traversal>,
--- but you can also remove targets.
-type Wither s t a b = forall f. Applicative f => WitherLike f s t a b
-
--- | A simple 'WitherLike'.
-type WitherLike' f s a = WitherLike f s s a a
-
--- | A simple 'Wither'.
-type Wither' s a = forall f. Applicative f => WitherLike' f s a
-
--- | This is used to characterize and clone a 'Filter'.
--- Since @FilterLike (Peat a b) s t a b@ is monomorphic, it can be used to store a filter in a container.
-newtype Peat a b t = Peat { runPeat :: forall f. Applicative f => (a -> f (Maybe b)) -> f t }
-
-instance Functor (Peat a b) where
-  fmap f (Peat k) = Peat (fmap f . k)
-  {-# INLINE fmap #-}
-
-instance Applicative (Peat a b) where
-  pure a = Peat $ const (pure a)
-  {-# INLINE pure #-}
-  Peat f <*> Peat g = Peat $ \h -> f h <*> g h
-  {-# INLINE (<*>) #-}
-#if MIN_VERSION_base(4,10,0)
-  liftA2 f (Peat xs) (Peat ys) = Peat $ \h -> liftA2 f (xs h) (ys h)
-  {-# INLINE liftA2 #-}
-#endif
-
--- | Reconstitute a 'Filter' from its monomorphic form.
-cloneFilter :: FilterLike (Peat a b) s t a b -> Filter s t a b
-cloneFilter l f = (\a -> a `runPeat` f) . l (\a -> Peat $ \g -> g a)
-{-# INLINABLE cloneFilter #-}
-
--- | 'witherOf' is actually 'id', but left for consistency.
-witherOf :: FilterLike f s t a b -> (a -> f (Maybe b)) -> s -> f t
-witherOf = id
-{-# INLINE witherOf #-}
-
--- | @'forMaybeOf' ≡ 'flip'@
-forMaybeOf :: FilterLike f s t a b -> s -> (a -> f (Maybe b)) -> f t
-forMaybeOf = flip
-{-# INLINE forMaybeOf #-}
-
--- In case mapMaybeOf or filterOf is called with a function of
--- unknown arity, we don't want to slow things down to raise
--- its arity.
-idDot :: (a -> b) -> a -> Identity b
-idDot = coerce
-
--- | 'mapMaybe' through a filter.
-mapMaybeOf :: FilterLike Identity s t a b -> (a -> Maybe b) -> s -> t
-mapMaybeOf w f = runIdentity . w (idDot f)
-{-# INLINE mapMaybeOf #-}
-
--- | 'catMaybes' through a filter.
-catMaybesOf :: FilterLike Identity s t (Maybe a) a -> s -> t
-catMaybesOf w = mapMaybeOf w id
-{-# INLINE catMaybesOf #-}
-
--- | 'filterA' through a filter.
-filterAOf :: Functor f => FilterLike' f s a -> (a -> f Bool) -> s -> f s
-filterAOf w f = w $ \a -> (\b -> if b then Just a else Nothing) <$> f a
-{-# INLINABLE filterAOf #-}
-
--- | Filter each element of a structure targeted by a 'Filter'.
-filterOf :: FilterLike' Identity s a -> (a -> Bool) -> s -> s
-filterOf w f = runIdentity . filterAOf w (idDot f)
-{-# INLINE filterOf #-}
-
--- | Remove the duplicate elements through a filter.
-ordNubOf :: Ord a => FilterLike' (State (Set.Set a)) s a -> s -> s
-ordNubOf w = ordNubOnOf w id
-
--- | Remove the duplicate elements through a filter.
-ordNubOnOf :: Ord b => FilterLike' (State (Set.Set b)) s a -> (a -> b) -> s -> s
-ordNubOnOf w p t = evalState (w f t) Set.empty
-  where
-    f a = let b = p a in state $ \s -> if Set.member b s
-      then (Nothing, s)
-      else (Just a, Set.insert b s)
-{-# INLINE ordNubOf #-}
-
--- | Remove the duplicate elements through a filter.
--- It is often faster than 'ordNubOf', especially when the comparison is expensive.
-hashNubOf :: (Eq a, Hashable a) => FilterLike' (State (HSet.HashSet a)) s a -> s -> s
-hashNubOf w = hashNubOnOf w id
-
--- | Remove the duplicate elements through a filter.
-hashNubOnOf :: (Eq b, Hashable b) => FilterLike' (State (HSet.HashSet b)) s a -> (a -> b) -> s -> s
-hashNubOnOf w p t = evalState (w f t) HSet.empty
-  where
-    f a = let b = p a in state $ \s -> if HSet.member b s
-      then (Nothing, s)
-      else (Just a, HSet.insert b s)
-{-# INLINE hashNubOf #-}
diff --git a/src/Witherable.hs b/src/Witherable.hs
--- a/src/Witherable.hs
+++ b/src/Witherable.hs
@@ -84,6 +84,7 @@
 --
 -- [/composition/]
 --   @'mapMaybe' f . 'mapMaybe' g ≡ 'mapMaybe' (f <=< g)@
+--
 class Functor f => Filterable f where
   -- | Like 'Maybe.mapMaybe'.
   mapMaybe :: (a -> Maybe b) -> f a -> f b
@@ -100,6 +101,14 @@
   filter f = mapMaybe $ \a -> if f a then Just a else Nothing
   {-# INLINE filter #-}
 
+  -- | Empty a filterable.
+  --
+  -- @'drain' ≡ 'mapMaybe' (const Nothing)@
+  --
+  drain :: f a -> f b
+  drain = mapMaybe (const Nothing)
+  {-# INLINE drain #-}
+
   {-# MINIMAL mapMaybe | catMaybes #-}
 
 -- | An enhancement of 'Traversable' with 'Filterable'
@@ -169,6 +178,7 @@
 
 instance Filterable Maybe where
   mapMaybe f = (>>= f)
+  drain _ = Nothing
   {-# INLINE mapMaybe #-}
 
 instance Witherable Maybe where
@@ -180,6 +190,7 @@
 
 instance Filterable Option where
   mapMaybe f = (>>= Option . f)
+  drain _ = Option Nothing
   {-# INLINE mapMaybe #-}
 
 instance Witherable Option where
@@ -197,6 +208,9 @@
   mapMaybe f (Right a) = maybe (Left mempty) Right $ f a
   {-# INLINABLE mapMaybe #-}
 
+  drain (Left e)  = Left e
+  drain (Right _) = Left mempty
+
 instance Monoid e => Witherable (Either e) where
   wither _ (Left e) = pure (Left e)
   wither f (Right a) = fmap (maybe (Left mempty) Right) (f a)
@@ -206,11 +220,13 @@
   mapMaybe = Maybe.mapMaybe
   catMaybes = Maybe.catMaybes
   filter = Prelude.filter
+  drain _ = []
 
 instance Filterable ZipList where
   mapMaybe f = ZipList . Maybe.mapMaybe f . getZipList
   catMaybes = ZipList . Maybe.catMaybes . getZipList
   filter f = ZipList . Prelude.filter f . getZipList
+  drain _ = ZipList []
 
 -- | Methods are good consumers for fusion.
 instance Witherable [] where
@@ -236,12 +252,14 @@
 instance Filterable IM.IntMap where
   mapMaybe = IM.mapMaybe
   filter = IM.filter
+  drain _ = IM.empty
 
 instance Witherable IM.IntMap where
 
 instance Filterable (M.Map k) where
   mapMaybe = M.mapMaybe
   filter = M.filter
+  drain _ = M.empty
 
 instance Witherable (M.Map k) where
 #if MIN_VERSION_containers(0,5,8)
@@ -251,6 +269,7 @@
 instance (Eq k, Hashable k) => Filterable (HM.HashMap k) where
   mapMaybe = HM.mapMaybe
   filter = HM.filter
+  drain _ = HM.empty
 
 instance (Eq k, Hashable k) => Witherable (HM.HashMap k) where
 
@@ -271,6 +290,7 @@
 instance Filterable V.Vector where
   filter   = V.filter
   mapMaybe = V.mapMaybe
+  drain _  = V.empty
 
 instance Witherable V.Vector where
   wither f = fmap V.fromList . wither f . V.toList
@@ -283,6 +303,7 @@
   mapMaybe f = S.fromList . mapMaybe f . F.toList
   {-# INLINABLE mapMaybe #-}
   filter = S.filter
+  drain _ = S.empty
 
 instance Witherable S.Seq where
   wither f = fmap S.fromList . wither f . F.toList
@@ -313,6 +334,7 @@
   mapMaybe f = Compose . fmap (mapMaybe f) . getCompose
   filter p = Compose . fmap (filter p) . getCompose
   catMaybes = Compose . fmap catMaybes . getCompose
+  drain = Compose . fmap drain . getCompose
 
 instance (T.Traversable f, Witherable g) => Witherable (Compose f g) where
   wither f = fmap Compose . T.traverse (wither f) . getCompose
@@ -323,6 +345,7 @@
   mapMaybe f (P.Pair x y) = P.Pair (mapMaybe f x) (mapMaybe f y)
   filter p (P.Pair x y) = P.Pair (filter p x) (filter p y)
   catMaybes (P.Pair x y) = P.Pair (catMaybes x) (catMaybes y)
+  drain (P.Pair x y) = P.Pair (drain x) (drain y)
 
 instance (Witherable f, Witherable g) => Witherable (P.Product f g) where
   wither f (P.Pair x y) = liftA2 P.Pair (wither f x) (wither f y)
@@ -339,6 +362,9 @@
   filter p (Sum.InL x) = Sum.InL (filter p x)
   filter p (Sum.InR y) = Sum.InR (filter p y)
 
+  drain (Sum.InL x) = Sum.InL (drain x)
+  drain (Sum.InR y) = Sum.InR (drain y)
+
 instance (Witherable f, Witherable g) => Witherable (Sum.Sum f g) where
   wither f (Sum.InL x) = Sum.InL <$> wither f x
   wither f (Sum.InR y) = Sum.InR <$> wither f y
@@ -470,13 +496,13 @@
   imapMaybe f = catMaybes . imap f
   {-# INLINE imapMaybe #-}
 
-  -- | @'ifilter' f . 'ifilter' g ≡ ifilter (\i -> 'liftA2' ('&&') (f i) (g i))@
+  -- | @'filter' f . 'ifilter' g ≡ ifilter (\i x -> f x '&&' g i x)@
   ifilter :: (i -> a -> Bool) -> t a -> t a
   ifilter f = imapMaybe $ \i a -> if f i a then Just a else Nothing
   {-# INLINE ifilter #-}
 
 -- | Indexed variant of 'Witherable'.
-class (TraversableWithIndex i t, Witherable t) => WitherableWithIndex i t | t -> i where
+class (TraversableWithIndex i t, FilterableWithIndex i t, Witherable t) => WitherableWithIndex i t | t -> i where
   -- | Effectful 'imapMaybe'.
   --
   -- @'iwither' (\ i -> 'pure' . f i) ≡ 'pure' . 'imapMaybe' f@
@@ -669,7 +695,7 @@
 hashNub = hashNubOn id
 {-# INLINE hashNub #-}
 
--- | The 'hashNubOn' function behaves just like 'ordNub',
+-- | The 'hashNubOn' function behaves just like 'hashNub',
 --   except it uses a another type to determine equivalence classes.
 --
 -- >>> hashNubOn fst [(True, 'x'), (False, 'y'), (True, 'z')]
diff --git a/witherable.cabal b/witherable.cabal
--- a/witherable.cabal
+++ b/witherable.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.4
 name:                witherable
-version:             0.4.2
+version:             0.5
 synopsis:            filterable traversable
 description:         A stronger variant of `traverse` which can remove elements and generalised mapMaybe, catMaybes, filter
 homepage:            https://github.com/fumieval/witherable
@@ -12,7 +12,8 @@
 category:            Data
 build-type:          Simple
 extra-source-files:  CHANGELOG.md
-tested-with:         GHC ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.4 || ==9.0.1
+tested-with:         GHC ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.7 ||
+                         ==9.0.1 || ==9.2.8 || ==9.4.8 || ==9.6.5 || ==9.8.2 || ==9.10.1
 
 source-repository head
   type: git
@@ -22,14 +23,13 @@
 library
   exposed-modules:
     Witherable
-    Data.Witherable
   build-depends:       base                          >=4.9      && <5,
-                       base-orphans                  >=0.8.4    && <0.9,
-                       containers                    >=0.5.7.1  && <0.7,
-                       hashable                      >=1.2.7.0  && <1.4,
-                       transformers                  >=0.5.2.0  && <0.6,
+                       base-orphans                  >=0.8.4    && <0.10,
+                       containers                    >=0.5.7.1  && <0.8,
+                       hashable                      >=1.2.7.0  && <1.5,
+                       transformers                  >=0.5.2.0  && <0.7,
                        unordered-containers          >=0.2.12.0 && <0.3,
-                       vector                        >=0.12.2.0 && <0.13,
+                       vector                        >=0.12.2.0 && <0.14,
                        indexed-traversable           >=0.1.1    && <0.2,
                        indexed-traversable-instances >=0.1      && <0.2
   hs-source-dirs:      src
