diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,18 @@
 # Monoidal containers
 
+# 0.6.1.0
+
+  * Drop official support for GHC 7.8.4
+  * Require containers 0.5.9 or greater.
+  * Support lens-5, semialign-1.2, and aeson-2
+  * MonoidalMap and MonoidalMap.Strict: Add several functions added to Data.Map since 0.5 up to 0.5.9:
+    `take`, `drop`, `splitAt`, `lookupMin`, `lookupMax`, `restrictKeys`,
+    `withoutKeys`, `fromDescList`,  `fromDescListWith`, `fromDescListWithKey`,
+    `fromDistinctDescList`, `takeWhileAntitone`, `dropWhileAntitone`,
+    `spanAntitone`, and `traverseMaybeWithKey`
+  * Add instances of `Filterable` and `Witherable` from the `witherable` package
+  * Add `Control.Lens.Wrapped.Rewrapped` instances.
+  
 # 0.6.0.1
 
   * Support semialign-1.1
diff --git a/monoidal-containers.cabal b/monoidal-containers.cabal
--- a/monoidal-containers.cabal
+++ b/monoidal-containers.cabal
@@ -1,34 +1,36 @@
-name:                monoidal-containers
-version:             0.6.0.1
-synopsis:            Containers with monoidal accumulation
+name:               monoidal-containers
+version:            0.6.1.0
+synopsis:           Containers with monoidal accumulation
 description:
-    Containers with merging via monoidal accumulation. The 'Monoid' instances
-    provided by the @containers@ and @unordered-containers@ packages merge
-    structures in a left-biased manner instead of using the underlying monoidal
-    structure of the value.
-    .
-    This package wraps the types provided by these packages, but provides @Monoid@
-    instances implemented in terms of the value type's 'mappend'. For instance,
-    the @Monoid@ @Map@ instance looks like,
-    .
-    @
-    instance (Ord k, Semigroup a) => Monoid (MonoidalMap k a)
-    @
-homepage:            http://github.com/bgamari/monoidal-containers
-license:             BSD3
-license-file:        LICENSE
-author:              Ben Gamari
-maintainer:          ben@smart-cactus.org
-copyright:           (c) 2014 Ben Gamari
-category:            Data
-build-type:          Simple
-cabal-version:       >=1.10
-extra-source-files:  Changelog.md
-tested-with:         GHC ==7.8.4, GHC ==8.0.2, GHC ==8.2.2, GHC ==8.4.3, GHC ==8.6.5, GHC ==8.8.1
+  Containers with merging via monoidal accumulation. The 'Monoid' instances
+  provided by the @containers@ and @unordered-containers@ packages merge
+  structures in a left-biased manner instead of using the underlying monoidal
+  structure of the value.
+  .
+  This package wraps the types provided by these packages, but provides @Monoid@
+  instances implemented in terms of the value type's 'mappend'. For instance,
+  the @Monoid@ @Map@ instance looks like,
+  .
+  @
+  instance (Ord k, Semigroup a) => Monoid (MonoidalMap k a)
+  @
 
+homepage:           http://github.com/bgamari/monoidal-containers
+license:            BSD3
+license-file:       LICENSE
+author:             Ben Gamari
+maintainer:         ben@smart-cactus.org
+copyright:          (c) 2014 Ben Gamari
+category:           Data
+build-type:         Simple
+cabal-version:      >=1.10
+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.2
+
 source-repository head
-  type:                git
-  location:            git://github.com/bgamari/monoidal-containers
+  type:     git
+  location: git://github.com/bgamari/monoidal-containers
 
 flag split-these
   description: Use split these/semialign packages
@@ -36,32 +38,38 @@
   default:     True
 
 library
-  exposed-modules:     Data.Map.Monoidal
-                       Data.HashMap.Monoidal
-                       Data.IntMap.Monoidal
-                       Data.Map.Monoidal.Strict
-                       Data.IntMap.Monoidal.Strict
-  other-extensions:    CPP,
-                       MultiParamTypeClasses,
-                       GeneralizedNewtypeDeriving,
-                       DeriveTraversable,
-                       DeriveDataTypeable
-  build-depends:       base >=4.7 && <4.14,
-                       aeson >=1.0 && <1.5,
-                       containers >=0.5 && <0.7,
-                       deepseq >=1.3 && <1.5,
-                       unordered-containers >= 0.2 && < 0.3,
-                       hashable >= 1.2 && < 1.4,
-                       lens >=4.4 && <5,
-                       newtype >=0.2 && <0.3,
-                       semigroups >= 0.18 && < 0.20
+  exposed-modules:
+    Data.HashMap.Monoidal
+    Data.IntMap.Monoidal
+    Data.IntMap.Monoidal.Strict
+    Data.Map.Monoidal
+    Data.Map.Monoidal.Strict
 
+  other-extensions:
+    CPP
+    DeriveDataTypeable
+    DeriveTraversable
+    GeneralizedNewtypeDeriving
+    MultiParamTypeClasses
+
+  build-depends:
+      aeson                 >=1.0   && <2.1
+    , base                  >=4.7   && <4.16
+    , containers            >=0.5.9 && <0.7
+    , deepseq               >=1.3   && <1.5
+    , hashable              >=1.2   && <1.4
+    , lens                  >=4.4   && <5.1
+    , newtype               >=0.2   && <0.3
+    , unordered-containers  >=0.2   && <0.3
+    , witherable            >=0.4   && <0.5
+
   if flag(split-these)
-    build-depends:     these >= 1 && <1.1,
-                       semialign >=1 && <1.2
-                    
+    build-depends:
+        semialign  >=1 && <1.3
+      , these      >=1 && <1.2
+
   else
-    build-depends:     these >= 0.7 && <0.9
+    build-depends: these >=0.7 && <0.9
 
-  hs-source-dirs:      src
-  default-language:    Haskell2010
+  hs-source-dirs:   src
+  default-language: Haskell2010
diff --git a/src/Data/HashMap/Monoidal.hs b/src/Data/HashMap/Monoidal.hs
--- a/src/Data/HashMap/Monoidal.hs
+++ b/src/Data/HashMap/Monoidal.hs
@@ -61,10 +61,12 @@
 import Control.Newtype
 import Data.Align
 #ifdef MIN_VERSION_semialign
+import Data.Semialign (Unalign)
 #if MIN_VERSION_semialign(1,1,0)
 import Data.Zip (Zip)
 #endif
 #endif
+import qualified Witherable
 
 -- | A 'HashMap' with monoidal accumulation
 newtype MonoidalHashMap k a = MonoidalHashMap { getMonoidalHashMap :: M.HashMap k a }
@@ -77,10 +79,12 @@
              , Semialign
 #endif
 #ifdef MIN_VERSION_semialign
+             , Unalign
 #if MIN_VERSION_semialign(1,1,0)
              , Zip
 #endif
 #endif
+             , Witherable.Filterable
              )
 
 type instance Index (MonoidalHashMap k a) = k
@@ -115,6 +119,10 @@
     _Wrapped' = iso unpack pack
     {-# INLINE _Wrapped' #-}
 
+instance (Eq k, Hashable k) => Rewrapped (M.HashMap k a) (MonoidalHashMap k a)
+
+instance (Eq k, Hashable k) => Rewrapped (MonoidalHashMap k a) (M.HashMap k a)
+
 instance (Eq k, Hashable k, Semigroup a) => Semigroup (MonoidalHashMap k a) where
     MonoidalHashMap a <> MonoidalHashMap b = MonoidalHashMap $ M.unionWith (<>) a b
     {-# INLINE (<>) #-}
@@ -141,6 +149,8 @@
     toList = M.toList . unpack
     {-# INLINE toList #-}
 #endif
+
+instance (Eq k, Hashable k) => Witherable.Witherable (MonoidalHashMap k)
 
 -- | /O(1)/. A map with a single element.
 singleton :: (Eq k, Hashable k) => k -> a -> MonoidalHashMap k a
diff --git a/src/Data/IntMap/Monoidal.hs b/src/Data/IntMap/Monoidal.hs
--- a/src/Data/IntMap/Monoidal.hs
+++ b/src/Data/IntMap/Monoidal.hs
@@ -147,15 +147,15 @@
 import Control.Lens
 import Control.Newtype
 import Data.Aeson(FromJSON, ToJSON, FromJSON1, ToJSON1)
-#if MIN_VERSION_containers(0,5,9)
 import Data.Functor.Classes
-#endif
 import Data.Align
 #ifdef MIN_VERSION_semialign
+import Data.Semialign (Unalign)
 #if MIN_VERSION_semialign(1,1,0)
 import Data.Zip (Zip)
 #endif
 #endif
+import qualified Witherable
 
 -- | An 'IntMap' with monoidal accumulation
 newtype MonoidalIntMap a = MonoidalIntMap { getMonoidalIntMap :: M.IntMap a }
@@ -167,17 +167,17 @@
              , Semialign
 #endif
 #ifdef MIN_VERSION_semialign
+             , Unalign
 #if MIN_VERSION_semialign(1,1,0)
              , Zip
 #endif
 #endif
+             , Witherable.Filterable
              )
 
-#if MIN_VERSION_containers(0,5,9)
 deriving instance Eq1 MonoidalIntMap
 deriving instance Ord1 MonoidalIntMap
 deriving instance Show1 MonoidalIntMap
-#endif
 
 type instance Index (MonoidalIntMap a) = Int
 type instance IxValue (MonoidalIntMap a) = a
@@ -244,6 +244,8 @@
     toList = M.toList . unpack
     {-# INLINE toList #-}
 #endif
+
+instance Witherable.Witherable MonoidalIntMap
 
 -- | /O(1)/. A map with a single element.
 singleton :: Int -> a -> MonoidalIntMap a
diff --git a/src/Data/IntMap/Monoidal/Strict.hs b/src/Data/IntMap/Monoidal/Strict.hs
--- a/src/Data/IntMap/Monoidal/Strict.hs
+++ b/src/Data/IntMap/Monoidal/Strict.hs
@@ -147,15 +147,15 @@
 import Control.Lens
 import Control.Newtype
 import Data.Aeson(FromJSON, ToJSON, FromJSON1, ToJSON1)
-#if MIN_VERSION_containers(0,5,9)
 import Data.Functor.Classes
-#endif
 import Data.Align
 #ifdef MIN_VERSION_semialign
+import Data.Semialign (Unalign)
 #if MIN_VERSION_semialign(1,1,0)
 import Data.Zip (Zip)
 #endif
 #endif
+import qualified Witherable
 
 -- | An 'IntMap' with monoidal accumulation
 newtype MonoidalIntMap a = MonoidalIntMap { getMonoidalIntMap :: M.IntMap a }
@@ -164,20 +164,20 @@
               FromJSON, ToJSON, FromJSON1, ToJSON1,
               Data, Typeable, Align
 #if MIN_VERSION_these(0,8,0)
-              , Semialign
+             , Semialign
 #endif
 #ifdef MIN_VERSION_semialign
+             , Unalign
 #if MIN_VERSION_semialign(1,1,0)
              , Zip
 #endif
 #endif
+             , Witherable.Filterable
              )
 
-#if MIN_VERSION_containers(0,5,9)
 deriving instance Eq1 MonoidalIntMap
 deriving instance Ord1 MonoidalIntMap
 deriving instance Show1 MonoidalIntMap
-#endif
 
 type instance Index (MonoidalIntMap a) = Int
 type instance IxValue (MonoidalIntMap a) = a
@@ -244,6 +244,8 @@
     toList = M.toList . unpack
     {-# INLINE toList #-}
 #endif
+
+instance Witherable.Witherable MonoidalIntMap
 
 -- | /O(1)/. A map with a single element.
 singleton :: Int -> a -> MonoidalIntMap a
diff --git a/src/Data/Map/Monoidal.hs b/src/Data/Map/Monoidal.hs
--- a/src/Data/Map/Monoidal.hs
+++ b/src/Data/Map/Monoidal.hs
@@ -28,6 +28,7 @@
     , assocs
     , elems
     , keys
+    , (!?)
     , (!)
     , (\\)
     , adjust
@@ -35,6 +36,11 @@
     , alter
     , delete
     , deleteAt
+    , take
+    , drop
+    , splitAt
+    , lookupMin
+    , lookupMax
     , deleteFindMax
     , deleteFindMin
     , deleteMax
@@ -46,6 +52,8 @@
     , empty
     , filter
     , filterWithKey
+    , restrictKeys
+    , withoutKeys
     , findIndex
     , findMax
     , findMin
@@ -63,6 +71,10 @@
     , fromAscListWithKey
     , fromDistinctAscList
     , fromDistinctList
+    , fromDescList
+    , fromDescListWith
+    , fromDescListWithKey
+    , fromDistinctDescList
     , fromList
     , fromListWith
     , fromListWithKey
@@ -104,6 +116,9 @@
     , null
     , partition
     , partitionWithKey
+    , takeWhileAntitone
+    , dropWhileAntitone
+    , spanAntitone
     , split
     , splitLookup
     , splitRoot
@@ -111,6 +126,7 @@
     , toDescList
     , toList
     , traverseWithKey
+    , traverseMaybeWithKey
     , unionWith
     , unionWithKey
     , unionsWith
@@ -127,7 +143,7 @@
     -- , showTreeWith
     ) where
 
-import Prelude hiding (null, lookup, map, foldl, foldr, filter)
+import Prelude hiding (null, lookup, map, foldl, foldr, filter, take, drop, splitAt)
 
 import Data.Coerce (coerce)
 import Data.Set (Set)
@@ -147,15 +163,15 @@
 import Control.Lens
 import Control.Newtype
 import Data.Aeson(FromJSON, ToJSON, FromJSON1, ToJSON1)
-#if MIN_VERSION_containers(0,5,9)
 import Data.Functor.Classes
-#endif
 import Data.Align
 #ifdef MIN_VERSION_semialign
+import Data.Semialign (Unalign)
 #if MIN_VERSION_semialign(1,1,0)
 import Data.Zip (Zip)
 #endif
 #endif
+import qualified Witherable
 
 -- | A 'Map' with monoidal accumulation
 newtype MonoidalMap k a = MonoidalMap { getMonoidalMap :: M.Map k a }
@@ -167,17 +183,17 @@
              , Semialign
 #endif
 #ifdef MIN_VERSION_semialign
+             , Unalign
 #if MIN_VERSION_semialign(1,1,0)
              , Zip
 #endif
 #endif
+             , Witherable.Filterable
              )
 
-#if MIN_VERSION_containers(0,5,9)
 deriving instance (Ord k) => Eq1 (MonoidalMap k)
 deriving instance (Ord k) => Ord1 (MonoidalMap k)
 deriving instance (Show k) => Show1 (MonoidalMap k)
-#endif
 
 type instance Index (MonoidalMap k a) = k
 type instance IxValue (MonoidalMap k a) = a
@@ -218,6 +234,10 @@
     _Wrapped' = iso unpack pack
     {-# INLINE _Wrapped' #-}
 
+instance Ord k => Rewrapped (M.Map k a) (MonoidalMap k a)
+
+instance Ord k => Rewrapped (MonoidalMap k a) (M.Map k a)
+
 instance (Ord k, Semigroup a) => Semigroup (MonoidalMap k a) where
     MonoidalMap a <> MonoidalMap b = MonoidalMap $ M.unionWith (<>) a b
     {-# INLINE (<>) #-}
@@ -245,6 +265,8 @@
     {-# INLINE toList #-}
 #endif
 
+instance Ord k => Witherable.Witherable (MonoidalMap k)
+
 -- | /O(1)/. A map with a single element.
 singleton :: k -> a -> MonoidalMap k a
 singleton k a = MonoidalMap $ M.singleton k a
@@ -295,6 +317,10 @@
 keys = M.keys . unpack
 {-# INLINE keys #-}
 
+(!?) :: forall k a. Ord k => MonoidalMap k a -> k -> Maybe a
+(!?) m k = (coerce m) !? k
+infixl 9 !?
+{-# INLINE (!?) #-}
 
 
 (!) :: forall k a. Ord k => MonoidalMap k a -> k -> a
@@ -421,6 +447,10 @@
 traverseWithKey = itraverse
 {-# INLINE traverseWithKey #-}
 
+traverseMaybeWithKey :: forall f k a b. Applicative f => (k -> a -> f (Maybe b)) -> MonoidalMap k a -> f (MonoidalMap k b)
+traverseMaybeWithKey f m = coerce <$> M.traverseMaybeWithKey f (coerce m)
+{-# INLINE traverseMaybeWithKey #-}
+
 mapAccum :: forall k a b c. (a -> b -> (a, c)) -> a -> MonoidalMap k b -> (a, MonoidalMap k c)
 mapAccum = coerce (M.mapAccum :: (a -> b -> (a, c)) -> a -> M.Map k b -> (a, M.Map k c))
 {-# INLINE mapAccum #-}
@@ -551,6 +581,22 @@
 fromDistinctList = coerce (M.fromList :: [(k, a)] -> M.Map k a)
 {-# INLINE fromDistinctList #-}
 
+fromDescList :: forall k a. Eq k => [(k, a)] -> MonoidalMap k a
+fromDescList = coerce (M.fromDescList :: [(k, a)] -> M.Map k a)
+{-# INLINE fromDescList #-}
+
+fromDescListWith :: forall k a. Eq k => (a -> a -> a) -> [(k, a)] -> MonoidalMap k a
+fromDescListWith = coerce (M.fromDescListWith :: (a -> a -> a) -> [(k, a)] -> M.Map k a)
+{-# INLINE fromDescListWith #-}
+
+fromDescListWithKey :: forall k a. Eq k => (k -> a -> a -> a) -> [(k, a)] -> MonoidalMap k a
+fromDescListWithKey = coerce (M.fromDescListWithKey :: (k -> a -> a -> a) -> [(k, a)] -> M.Map k a)
+{-# INLINE fromDescListWithKey #-}
+
+fromDistinctDescList :: forall k a. [(k, a)] -> MonoidalMap k a
+fromDistinctDescList = coerce (M.fromDistinctDescList :: [(k, a)] -> M.Map k a)
+{-# INLINE fromDistinctDescList #-}
+
 filter :: forall k a. (a -> Bool) -> MonoidalMap k a -> MonoidalMap k a
 filter = coerce (M.filter :: (a -> Bool) -> M.Map k a -> M.Map k a)
 {-# INLINE filter #-}
@@ -559,6 +605,14 @@
 filterWithKey = coerce (M.filterWithKey :: (k -> a -> Bool) -> M.Map k a -> M.Map k a)
 {-# INLINE filterWithKey #-}
 
+restrictKeys :: forall k a. Ord k => MonoidalMap k a -> Set k -> MonoidalMap k a
+restrictKeys = coerce (M.restrictKeys :: M.Map k a -> Set k -> M.Map k a)
+{-# INLINE restrictKeys #-}
+
+withoutKeys :: forall k a. Ord k => MonoidalMap k a -> Set k -> MonoidalMap k a
+withoutKeys = coerce (M.withoutKeys :: M.Map k a -> Set k -> M.Map k a)
+{-# INLINE withoutKeys #-}
+
 partition :: forall k a. (a -> Bool) -> MonoidalMap k a -> (MonoidalMap k a, MonoidalMap k a)
 partition = coerce (M.partition :: (a -> Bool) -> M.Map k a -> (M.Map k a, M.Map k a))
 {-# INLINE partition #-}
@@ -567,6 +621,18 @@
 partitionWithKey = coerce (M.partitionWithKey :: (k -> a -> Bool) -> M.Map k a -> (M.Map k a, M.Map k a))
 {-# INLINE partitionWithKey #-}
 
+takeWhileAntitone :: forall k a. (k -> Bool) -> MonoidalMap k a -> MonoidalMap k a
+takeWhileAntitone = coerce (M.takeWhileAntitone :: (k -> Bool) -> M.Map k a -> M.Map k a)
+{-# INLINE takeWhileAntitone #-}
+
+dropWhileAntitone :: forall k a. (k -> Bool) -> MonoidalMap k a -> MonoidalMap k a
+dropWhileAntitone = coerce (M.dropWhileAntitone :: (k -> Bool) -> M.Map k a -> M.Map k a)
+{-# INLINE dropWhileAntitone #-}
+
+spanAntitone :: forall k a. (k -> Bool) -> MonoidalMap k a -> (MonoidalMap k a, MonoidalMap k a)
+spanAntitone = coerce (M.spanAntitone :: (k -> Bool) -> M.Map k a -> (M.Map k a, M.Map k a))
+{-# INLINE spanAntitone #-}
+
 mapMaybe :: forall k a b. (a -> Maybe b) -> MonoidalMap k a -> MonoidalMap k b
 mapMaybe = coerce (M.mapMaybe :: (a -> Maybe b) -> M.Map k a -> M.Map k b)
 {-# INLINE mapMaybe #-}
@@ -631,6 +697,26 @@
 deleteAt = coerce (M.deleteAt :: Int -> M.Map k a -> M.Map k a)
 {-# INLINE deleteAt #-}
 
+take :: forall k a. Int -> MonoidalMap k a -> MonoidalMap k a
+take = coerce (M.take :: Int -> M.Map k a -> M.Map k a)
+{-# INLINE take #-}
+
+drop :: forall k a. Int -> MonoidalMap k a -> MonoidalMap k a
+drop = coerce (M.drop :: Int -> M.Map k a -> M.Map k a)
+{-# INLINE drop #-}
+
+splitAt :: forall k a. Int -> MonoidalMap k a -> (MonoidalMap k a, MonoidalMap k a)
+splitAt = coerce (M.splitAt :: Int -> M.Map k a -> (M.Map k a, M.Map k a))
+{-# INLINE splitAt #-}
+
+lookupMin :: forall k a. MonoidalMap k a -> Maybe (k, a)
+lookupMin = coerce (M.lookupMin :: M.Map k a -> Maybe (k, a))
+{-# INLINE lookupMin #-}
+
+lookupMax :: forall k a. MonoidalMap k a -> Maybe (k, a)
+lookupMax = coerce (M.lookupMax :: M.Map k a -> Maybe (k, a))
+{-# INLINE lookupMax #-}
+
 findMin :: forall k a. MonoidalMap k a -> (k, a)
 findMin = coerce (M.findMin :: M.Map k a -> (k, a))
 {-# INLINE findMin #-}
@@ -698,5 +784,3 @@
 valid :: forall k a. Ord k => MonoidalMap k a -> Bool
 valid = coerce (M.valid :: Ord k => M.Map k a -> Bool)
 {-# INLINE valid #-}
-
-
diff --git a/src/Data/Map/Monoidal/Strict.hs b/src/Data/Map/Monoidal/Strict.hs
--- a/src/Data/Map/Monoidal/Strict.hs
+++ b/src/Data/Map/Monoidal/Strict.hs
@@ -1,11 +1,11 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE DeriveTraversable #-}
 {-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE StandaloneDeriving #-}
 
 -- | This module provides a 'Data.Map' variant which uses the value's
@@ -28,6 +28,7 @@
     , assocs
     , elems
     , keys
+    , (!?)
     , (!)
     , (\\)
     , adjust
@@ -35,6 +36,11 @@
     , alter
     , delete
     , deleteAt
+    , take
+    , drop
+    , splitAt
+    , lookupMin
+    , lookupMax
     , deleteFindMax
     , deleteFindMin
     , deleteMax
@@ -46,6 +52,8 @@
     , empty
     , filter
     , filterWithKey
+    , restrictKeys
+    , withoutKeys
     , findIndex
     , findMax
     , findMin
@@ -63,6 +71,10 @@
     , fromAscListWithKey
     , fromDistinctAscList
     , fromDistinctList
+    , fromDescList
+    , fromDescListWith
+    , fromDescListWithKey
+    , fromDistinctDescList
     , fromList
     , fromListWith
     , fromListWithKey
@@ -104,6 +116,9 @@
     , null
     , partition
     , partitionWithKey
+    , takeWhileAntitone
+    , dropWhileAntitone
+    , spanAntitone
     , split
     , splitLookup
     , splitRoot
@@ -111,6 +126,7 @@
     , toDescList
     , toList
     , traverseWithKey
+    , traverseMaybeWithKey
     , unionWith
     , unionWithKey
     , unionsWith
@@ -127,19 +143,19 @@
     -- , showTreeWith
     ) where
 
-import Prelude hiding (null, lookup, map, foldl, foldr, filter)
+import Prelude hiding (null, lookup, map, foldl, foldr, filter, take, drop, splitAt)
 
 import Data.Coerce (coerce)
+import Data.Set (Set)
 import Data.Semigroup
 import Data.Foldable (Foldable)
 import Data.Traversable (Traversable)
 import Control.Applicative (Applicative, pure)
 import Data.Data (Data)
 import Data.Typeable (Typeable)
-import Data.Set (Set)
 
 #if MIN_VERSION_base(4,7,0)
-import qualified GHC.Exts  as IsList
+import qualified GHC.Exts as IsList
 #endif
 
 import Control.DeepSeq
@@ -147,15 +163,15 @@
 import Control.Lens
 import Control.Newtype
 import Data.Aeson(FromJSON, ToJSON, FromJSON1, ToJSON1)
-#if MIN_VERSION_containers(0,5,9)
 import Data.Functor.Classes
-#endif
 import Data.Align
 #ifdef MIN_VERSION_semialign
+import Data.Semialign (Unalign)
 #if MIN_VERSION_semialign(1,1,0)
 import Data.Zip (Zip)
 #endif
 #endif
+import qualified Witherable
 
 -- | A 'Map' with monoidal accumulation
 newtype MonoidalMap k a = MonoidalMap { getMonoidalMap :: M.Map k a }
@@ -167,17 +183,17 @@
              , Semialign
 #endif
 #ifdef MIN_VERSION_semialign
+             , Unalign
 #if MIN_VERSION_semialign(1,1,0)
              , Zip
 #endif
 #endif
+             , Witherable.Filterable
              )
 
-#if MIN_VERSION_containers(0,5,9)
 deriving instance (Ord k) => Eq1 (MonoidalMap k)
 deriving instance (Ord k) => Ord1 (MonoidalMap k)
 deriving instance (Show k) => Show1 (MonoidalMap k)
-#endif
 
 type instance Index (MonoidalMap k a) = k
 type instance IxValue (MonoidalMap k a) = a
@@ -218,6 +234,10 @@
     _Wrapped' = iso unpack pack
     {-# INLINE _Wrapped' #-}
 
+instance Ord k => Rewrapped (M.Map k a) (MonoidalMap k a)
+
+instance Ord k => Rewrapped (MonoidalMap k a) (M.Map k a)
+
 instance (Ord k, Semigroup a) => Semigroup (MonoidalMap k a) where
     MonoidalMap a <> MonoidalMap b = MonoidalMap $ M.unionWith (<>) a b
     {-# INLINE (<>) #-}
@@ -245,6 +265,8 @@
     {-# INLINE toList #-}
 #endif
 
+instance Ord k => Witherable.Witherable (MonoidalMap k)
+
 -- | /O(1)/. A map with a single element.
 singleton :: k -> a -> MonoidalMap k a
 singleton k a = MonoidalMap $ M.singleton k a
@@ -295,7 +317,12 @@
 keys = M.keys . unpack
 {-# INLINE keys #-}
 
+(!?) :: forall k a. Ord k => MonoidalMap k a -> k -> Maybe a
+(!?) m k = (coerce m) !? k
+infixl 9 !?
+{-# INLINE (!?) #-}
 
+
 (!) :: forall k a. Ord k => MonoidalMap k a -> k -> a
 (!) = coerce ((M.!) :: M.Map k a -> k -> a)
 infixl 9 !
@@ -420,6 +447,10 @@
 traverseWithKey = itraverse
 {-# INLINE traverseWithKey #-}
 
+traverseMaybeWithKey :: forall f k a b. Applicative f => (k -> a -> f (Maybe b)) -> MonoidalMap k a -> f (MonoidalMap k b)
+traverseMaybeWithKey f m = coerce <$> M.traverseMaybeWithKey f (coerce m)
+{-# INLINE traverseMaybeWithKey #-}
+
 mapAccum :: forall k a b c. (a -> b -> (a, c)) -> a -> MonoidalMap k b -> (a, MonoidalMap k c)
 mapAccum = coerce (M.mapAccum :: (a -> b -> (a, c)) -> a -> M.Map k b -> (a, M.Map k c))
 {-# INLINE mapAccum #-}
@@ -432,8 +463,8 @@
 mapAccumRWithKey = coerce (M.mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> M.Map k b -> (a, M.Map k c))
 {-# INLINE mapAccumRWithKey #-}
 
-mapKeys :: forall k1 k2 a. (Ord k2, Semigroup a) => (k1 -> k2) -> MonoidalMap k1 a -> MonoidalMap k2 a
-mapKeys = mapKeysWith (<>)
+mapKeys :: forall k1 k2 a. Ord k2 => (k1 -> k2) -> MonoidalMap k1 a -> MonoidalMap k2 a
+mapKeys = coerce (M.mapKeys :: (k1 -> k2) -> M.Map k1 a -> M.Map k2 a)
 {-# INLINE mapKeys #-}
 
 mapKeysWith :: forall k1 k2 a. Ord k2 => (a -> a -> a) -> (k1 -> k2) -> MonoidalMap k1 a -> MonoidalMap k2 a
@@ -510,8 +541,8 @@
 toList = coerce (M.toList :: M.Map k a -> [(k, a)])
 {-# INLINE toList #-}
 
-fromList :: forall k a. (Ord k, Semigroup a) => [(k, a)] -> MonoidalMap k a
-fromList = fromListWith (<>)
+fromList :: forall k a. Ord k => [(k, a)] -> MonoidalMap k a
+fromList = coerce (M.fromList :: [(k, a)] -> M.Map k a)
 {-# INLINE fromList #-}
 
 fromListWith :: forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> MonoidalMap k a
@@ -530,8 +561,8 @@
 toDescList = coerce (M.toDescList :: M.Map k a -> [(k, a)])
 {-# INLINE toDescList #-}
 
-fromAscList :: forall k a. (Eq k, Semigroup a) => [(k, a)] -> MonoidalMap k a
-fromAscList = fromAscListWith (<>)
+fromAscList :: forall k a. Eq k => [(k, a)] -> MonoidalMap k a
+fromAscList = coerce (M.fromAscList :: [(k, a)] -> M.Map k a)
 {-# INLINE fromAscList #-}
 
 fromAscListWith :: forall k a. Eq k => (a -> a -> a) -> [(k, a)] -> MonoidalMap k a
@@ -550,6 +581,22 @@
 fromDistinctList = coerce (M.fromList :: [(k, a)] -> M.Map k a)
 {-# INLINE fromDistinctList #-}
 
+fromDescList :: forall k a. Eq k => [(k, a)] -> MonoidalMap k a
+fromDescList = coerce (M.fromDescList :: [(k, a)] -> M.Map k a)
+{-# INLINE fromDescList #-}
+
+fromDescListWith :: forall k a. Eq k => (a -> a -> a) -> [(k, a)] -> MonoidalMap k a
+fromDescListWith = coerce (M.fromDescListWith :: (a -> a -> a) -> [(k, a)] -> M.Map k a)
+{-# INLINE fromDescListWith #-}
+
+fromDescListWithKey :: forall k a. Eq k => (k -> a -> a -> a) -> [(k, a)] -> MonoidalMap k a
+fromDescListWithKey = coerce (M.fromDescListWithKey :: (k -> a -> a -> a) -> [(k, a)] -> M.Map k a)
+{-# INLINE fromDescListWithKey #-}
+
+fromDistinctDescList :: forall k a. [(k, a)] -> MonoidalMap k a
+fromDistinctDescList = coerce (M.fromDistinctDescList :: [(k, a)] -> M.Map k a)
+{-# INLINE fromDistinctDescList #-}
+
 filter :: forall k a. (a -> Bool) -> MonoidalMap k a -> MonoidalMap k a
 filter = coerce (M.filter :: (a -> Bool) -> M.Map k a -> M.Map k a)
 {-# INLINE filter #-}
@@ -558,6 +605,14 @@
 filterWithKey = coerce (M.filterWithKey :: (k -> a -> Bool) -> M.Map k a -> M.Map k a)
 {-# INLINE filterWithKey #-}
 
+restrictKeys :: forall k a. Ord k => MonoidalMap k a -> Set k -> MonoidalMap k a
+restrictKeys = coerce (M.restrictKeys :: M.Map k a -> Set k -> M.Map k a)
+{-# INLINE restrictKeys #-}
+
+withoutKeys :: forall k a. Ord k => MonoidalMap k a -> Set k -> MonoidalMap k a
+withoutKeys = coerce (M.withoutKeys :: M.Map k a -> Set k -> M.Map k a)
+{-# INLINE withoutKeys #-}
+
 partition :: forall k a. (a -> Bool) -> MonoidalMap k a -> (MonoidalMap k a, MonoidalMap k a)
 partition = coerce (M.partition :: (a -> Bool) -> M.Map k a -> (M.Map k a, M.Map k a))
 {-# INLINE partition #-}
@@ -566,6 +621,18 @@
 partitionWithKey = coerce (M.partitionWithKey :: (k -> a -> Bool) -> M.Map k a -> (M.Map k a, M.Map k a))
 {-# INLINE partitionWithKey #-}
 
+takeWhileAntitone :: forall k a. (k -> Bool) -> MonoidalMap k a -> MonoidalMap k a
+takeWhileAntitone = coerce (M.takeWhileAntitone :: (k -> Bool) -> M.Map k a -> M.Map k a)
+{-# INLINE takeWhileAntitone #-}
+
+dropWhileAntitone :: forall k a. (k -> Bool) -> MonoidalMap k a -> MonoidalMap k a
+dropWhileAntitone = coerce (M.dropWhileAntitone :: (k -> Bool) -> M.Map k a -> M.Map k a)
+{-# INLINE dropWhileAntitone #-}
+
+spanAntitone :: forall k a. (k -> Bool) -> MonoidalMap k a -> (MonoidalMap k a, MonoidalMap k a)
+spanAntitone = coerce (M.spanAntitone :: (k -> Bool) -> M.Map k a -> (M.Map k a, M.Map k a))
+{-# INLINE spanAntitone #-}
+
 mapMaybe :: forall k a b. (a -> Maybe b) -> MonoidalMap k a -> MonoidalMap k b
 mapMaybe = coerce (M.mapMaybe :: (a -> Maybe b) -> M.Map k a -> M.Map k b)
 {-# INLINE mapMaybe #-}
@@ -630,6 +697,26 @@
 deleteAt = coerce (M.deleteAt :: Int -> M.Map k a -> M.Map k a)
 {-# INLINE deleteAt #-}
 
+take :: forall k a. Int -> MonoidalMap k a -> MonoidalMap k a
+take = coerce (M.take :: Int -> M.Map k a -> M.Map k a)
+{-# INLINE take #-}
+
+drop :: forall k a. Int -> MonoidalMap k a -> MonoidalMap k a
+drop = coerce (M.drop :: Int -> M.Map k a -> M.Map k a)
+{-# INLINE drop #-}
+
+splitAt :: forall k a. Int -> MonoidalMap k a -> (MonoidalMap k a, MonoidalMap k a)
+splitAt = coerce (M.splitAt :: Int -> M.Map k a -> (M.Map k a, M.Map k a))
+{-# INLINE splitAt #-}
+
+lookupMin :: forall k a. MonoidalMap k a -> Maybe (k, a)
+lookupMin = coerce (M.lookupMin :: M.Map k a -> Maybe (k, a))
+{-# INLINE lookupMin #-}
+
+lookupMax :: forall k a. MonoidalMap k a -> Maybe (k, a)
+lookupMax = coerce (M.lookupMax :: M.Map k a -> Maybe (k, a))
+{-# INLINE lookupMax #-}
+
 findMin :: forall k a. MonoidalMap k a -> (k, a)
 findMin = coerce (M.findMin :: M.Map k a -> (k, a))
 {-# INLINE findMin #-}
@@ -697,5 +784,3 @@
 valid :: forall k a. Ord k => MonoidalMap k a -> Bool
 valid = coerce (M.valid :: Ord k => M.Map k a -> Bool)
 {-# INLINE valid #-}
-
-
