diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,25 @@
+# Revision history for dependent-map
+
+## Unreleased (0.4.0.1)
+
+* Minimum `base` version is now `4.11` (GHC 8.4.x).
+* Use canonical `mappend`/`(<>)` definitions.
+
+## 0.4.0.0 - 2020-03-26
+
+* Stop re-exporting `Some(..)`, `GCompare(..)`, and `GOrdering(..)` from `dependent-sum` (which itself re-exports from `some` in some versions).
+* Stop re-exporting `DSum(..)` from `dependent-sum`.
+
+## 0.3.1.0 - 2020-03-26
+
+* Drop support for non-GHC compilers.
+* Drop support for GHC < 8.
+* Update maintainer and GitHub links.
+* Support `dependent-sum` 0.7.
+* Add `ffor`, `fforWithKey`, `forWithKey`, `forWithKey_`, and `traverseWithKey_` to `Data.Dependent.Map`.
+* Enable `PolyKinds` for `Data.Dependent.Map.Lens`.
+
+## 0.3 - 2019-03-21
+
+* Change instances of Eq, Ord, Read, Show to use Has' from constraints-extras instead of *Tag classes.
+* This ends support for GHC 7.x.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,49 @@
+dependent-map [![Build Status](https://github.com/obsidiansystems/dependent-map/actions/workflows/haskell-ci.yml/badge.svg)](https://github.com/obsidiansystems/dependent-map/actions/workflows/haskell-ci.yml) [![Hackage](https://img.shields.io/hackage/v/dependent-map.svg)](http://hackage.haskell.org/package/dependent-map)
+==============
+
+This library defines a dependently-typed finite map type. It is derived from `Data.Map.Map` in the `containers` package, but rather than (conceptually) storing pairs indexed by the first component, it stores `DSum`s (from the `dependent-sum` package) indexed by tag. For example
+
+```haskell
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeFamilies #-}
+module Example where
+
+import Data.Constraint.Extras.TH (deriveArgDict)
+import Data.Dependent.Map (DMap, fromList, singleton, union, unionWithKey)
+import Data.Dependent.Sum ((==>))
+import Data.Functor.Identity (Identity(..))
+import Data.GADT.Compare.TH (deriveGCompare, deriveGEq)
+import Data.GADT.Show.TH (deriveGShow)
+
+data Tag a where
+  StringKey :: Tag String
+  IntKey    :: Tag Int
+  DoubleKey :: Tag Double
+deriveGEq ''Tag
+deriveGCompare ''Tag
+deriveGShow ''Tag
+deriveArgDict ''Tag
+
+x :: DMap Tag Identity
+x = fromList [DoubleKey ==> pi, StringKey ==> "hello there"]
+
+y :: DMap Tag Identity
+y = singleton IntKey (Identity 42)
+
+z :: DMap Tag Identity
+z = y `union` fromList [DoubleKey ==> -1.1415926535897931]
+
+addFoo :: Tag v -> Identity v -> Identity v -> Identity v
+addFoo IntKey (Identity x) (Identity y) = Identity $ x + y
+addFoo DoubleKey (Identity x) (Identity y) = Identity $ x + y
+addFoo _ x _ = x
+
+main :: IO ()
+main = mapM_ print
+  [ x, y, z
+  , unionWithKey addFoo x z
+  ]
+```
diff --git a/dependent-map.cabal b/dependent-map.cabal
--- a/dependent-map.cabal
+++ b/dependent-map.cabal
@@ -1,15 +1,15 @@
+cabal-version:          3.0
 name:                   dependent-map
-version:                0.2.4.0
+version:                0.4.0.1
 stability:              provisional
 
-cabal-version:          >= 1.6
 build-type:             Simple
 
 author:                 James Cook <mokus@deepbondi.net>
-maintainer:             James Cook <mokus@deepbondi.net>
-license:                OtherLicense
+maintainer:             Obsidian Systems, LLC <maintainer@obsidian.systems>
+license:                BSD-3-Clause
 license-file:           LICENSE
-homepage:               https://github.com/mokus0/dependent-map
+homepage:               https://github.com/obsidiansystems/dependent-map
 
 category:               Data, Dependent Types
 synopsis:               Dependent finite maps (partial dependent products)
@@ -17,30 +17,33 @@
                         @Data.Map.Map@, allowing keys to specify the type
                         of value that can be associated with them.
 
-tested-with:            GHC == 7.0.4,
-                        GHC == 7.2.2,
-                        GHC == 7.4.2,
-                        GHC == 7.6.3,
-                        GHC == 7.8.4,
-                        GHC == 7.10.1,
-                        GHC == 7.11
+extra-source-files: ChangeLog.md
+                    README.md
 
+tested-with:            GHC == 8.4.4,
+                        GHC == 8.6.5,
+                        GHC == 8.8.4,
+                        GHC == 8.10.7,
+                        GHC == 9.0.2,
+                        GHC == 9.2.8,
+                        GHC == 9.4.8,
+                        GHC == 9.6.5,
+                        GHC == 9.8.2,
+                        GHC == 9.10.1
+
 source-repository head
   type:     git
-  location: git://github.com/mokus0/dependent-map.git
+  location: https://github.com/obsidiansystems/dependent-map
 
 Library
   hs-source-dirs:       src
   ghc-options:          -fwarn-unused-imports -fwarn-unused-binds
-  exposed-modules:      Data.Dependent.Map
-  other-modules:        Data.Dependent.Map.Internal,
-                        Data.Dependent.Map.PtrEquality
-  if impl(ghc < 7.8)
-    other-modules:      Data.Dependent.Map.Typeable
-  if impl(ghc < 8)
-    build-depends:      semigroups
-  build-depends:        base >= 3 && < 5,
-                        containers,
-                        dependent-sum >= 0.3.2
-  if impl(ghc >= 7.2) && impl(ghc < 7.8)
-    ghc-options:        -trust base -trust dependent-sum
+  exposed-modules:      Data.Dependent.Map,
+                        Data.Dependent.Map.Lens,
+                        Data.Dependent.Map.Internal
+  other-modules:        Data.Dependent.Map.PtrEquality
+  build-depends:        base >= 4.11 && < 5,
+                        containers >= 0.5.7.1 && <0.8,
+                        dependent-sum >= 0.6.1 && < 0.8,
+                        constraints-extras >= 0.2.3.0 && < 0.5
+  default-language:     Haskell2010
diff --git a/src/Data/Dependent/Map.hs b/src/Data/Dependent/Map.hs
--- a/src/Data/Dependent/Map.hs
+++ b/src/Data/Dependent/Map.hs
@@ -1,19 +1,17 @@
-{-# LANGUAGE GADTs, RankNTypes #-}
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE CPP #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Trustworthy #-}
-#endif
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
-{-# LANGUAGE PolyKinds #-}
-#endif
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
 module Data.Dependent.Map
     ( DMap
-    , DSum(..), Some(..)
-    , GCompare(..), GOrdering(..)
-    
+
     -- * Operators
     , (!), (\\)
 
@@ -24,7 +22,7 @@
     , notMember
     , lookup
     , findWithDefault
-    
+
     -- * Construction
     , empty
     , singleton
@@ -37,7 +35,7 @@
     , insertWithKey'
     , insertLookupWithKey
     , insertLookupWithKey'
-    
+
     -- ** Delete\/Update
     , delete
     , adjust
@@ -47,11 +45,12 @@
     , updateWithKey
     , updateLookupWithKey
     , alter
+    , alterF
 
     -- * Combine
 
     -- ** Union
-    , union         
+    , union
     , unionWithKey
     , unions
     , unionsWithKey
@@ -59,16 +58,21 @@
     -- ** Difference
     , difference
     , differenceWithKey
-    
+
     -- ** Intersection
-    , intersection           
+    , intersection
     , intersectionWithKey
 
     -- * Traversal
     -- ** Map
     , map
+    , ffor
     , mapWithKey
+    , fforWithKey
+    , traverseWithKey_
+    , forWithKey_
     , traverseWithKey
+    , forWithKey
     , mapAccumLWithKey
     , mapAccumRWithKey
     , mapKeysWith
@@ -83,7 +87,7 @@
     -- * Conversion
     , keys
     , assocs
-    
+
     -- ** Lists
     , toList
     , fromList
@@ -96,22 +100,23 @@
     , fromAscListWithKey
     , fromDistinctAscList
 
-    -- * Filter 
+    -- * Filter
     , filter
     , filterWithKey
     , partitionWithKey
 
+    , mapMaybe
     , mapMaybeWithKey
     , mapEitherWithKey
 
-    , split         
-    , splitLookup   
+    , split
+    , splitLookup
 
     -- * Submap
     , isSubmapOf, isSubmapOfBy
     , isProperSubmapOf, isProperSubmapOfBy
 
-    -- * Indexed 
+    -- * Indexed
     , lookupIndex
     , findIndex
     , elemAt
@@ -131,7 +136,7 @@
     , updateMaxWithKey
     , minViewWithKey
     , maxViewWithKey
-    
+
     -- * Debugging
     , showTree
     , showTreeWith
@@ -140,37 +145,30 @@
 
 import Prelude hiding (null, lookup, map)
 import qualified Prelude
-#if !MIN_VERSION_base(4,8,0)
-import Control.Applicative (Applicative(..), (<$>))
-#endif
-import Data.Dependent.Map.Internal
-#if !MIN_VERSION_base(4,7,0)
-import Data.Dependent.Map.Typeable ({- instance Typeable ... -})
-#endif
-
-import Data.Dependent.Sum
-import Data.GADT.Compare
+import Data.Constraint.Extras (Has', has')
+import Data.Dependent.Sum (DSum((:=>)))
+import Data.GADT.Compare (GCompare, GEq, GOrdering(..), gcompare, geq)
+import Data.GADT.Show (GRead, GShow)
 import Data.Maybe (isJust)
-#if !MIN_VERSION_base(4,8,0)
-import Data.Monoid
-#endif
-import Data.Semigroup
-import Data.Some
-import Text.Read
-import Data.Dependent.Map.PtrEquality
+import Data.Some (Some, mkSome)
+import Data.Typeable ((:~:)(Refl))
+import Text.Read (Lexeme(Ident), lexP, parens, prec, readListPrec,
+                  readListPrecDefault, readPrec)
 
+import Data.Dependent.Map.Internal
+import Data.Dependent.Map.PtrEquality (ptrEq)
+
 instance (GCompare k) => Monoid (DMap k f) where
     mempty  = empty
-    mappend = union
     mconcat = unions
 
 instance (GCompare k) => Semigroup (DMap k f) where
-  (<>) = mappend
+  (<>) = union
 
 {--------------------------------------------------------------------
   Operators
 --------------------------------------------------------------------}
-infixl 9 !,\\ --
+infixl 9 \\,! -- \\ at the end of the line means line continuation
 
 -- | /O(log n)/. Find the value at a key.
 -- Calls 'error' when the element can not be found.
@@ -186,21 +184,21 @@
 m1 \\ m2 = difference m1 m2
 
 -- #if __GLASGOW_HASKELL__
--- 
+--
 -- {--------------------------------------------------------------------
---   A Data instance  
+--   A Data instance
 -- --------------------------------------------------------------------}
--- 
+--
 -- -- This instance preserves data abstraction at the cost of inefficiency.
 -- -- We omit reflection services for the sake of data abstraction.
--- 
+--
 -- instance (Data k, Data a, GCompare k) => Data (DMap k) where
 --   gfoldl f z m   = z fromList `f` toList m
 --   toConstr _     = error "toConstr"
 --   gunfold _ _    = error "gunfold"
 --   dataTypeOf _   = mkNoRepType "Data.Map.Map"
 --   dataCast2 f    = gcast2 f
--- 
+--
 -- #endif
 
 {--------------------------------------------------------------------
@@ -277,7 +275,7 @@
             GEQ -> t
 
 -- | /O(log n)/. Insert with a function, combining new value and old value.
--- @'insertWith' f key value mp@ 
+-- @'insertWith' f key value mp@
 -- will insert the entry @key :=> value@ into @mp@ if key does
 -- not exist in the map. If the key does exist, the function will
 -- insert the entry @key :=> f new_value old_value@.
@@ -290,7 +288,7 @@
 insertWith' f = insertWithKey' (\_ x' y' -> f x' y')
 
 -- | /O(log n)/. Insert with a function, combining key, new value and old value.
--- @'insertWithKey' f key value mp@ 
+-- @'insertWithKey' f key value mp@
 -- will insert the entry @key :=> value@ into @mp@ if key does
 -- not exist in the map. If the key does exist, the function will
 -- insert the entry @key :=> f key new_value old_value@.
@@ -425,7 +423,7 @@
 
 -- | /O(log n)/. Lookup and update. See also 'updateWithKey'.
 -- The function returns changed value, if it is updated.
--- Returns the original key value if the map entry is deleted. 
+-- Returns the original key value if the map entry is deleted.
 updateLookupWithKey :: forall k f v. GCompare k => (k v -> f v -> Maybe (f v)) -> k v -> DMap k f -> (Maybe (f v), DMap k f)
 updateLookupWithKey f k = k `seq` go
  where
@@ -434,7 +432,7 @@
    go (Bin sx kx x l r) =
           case gcompare k kx of
                GLT -> let (found,l') = go l in (found,balance kx x l' r)
-               GGT -> let (found,r') = go r in (found,balance kx x l r') 
+               GGT -> let (found,r') = go r in (found,balance kx x l r')
                GEQ -> case f kx x of
                        Just x' -> (Just x',Bin sx kx x' l r)
                        Nothing -> (Just x,glue l r)
@@ -457,6 +455,19 @@
                        Just x' -> Bin sx kx x' l r
                        Nothing -> glue l r
 
+-- | Works the same as 'alter' except the new value is returned in some 'Functor' @f@.
+-- In short : @(\v' -> alter (const v') k dm) <$> f (lookup k dm)@
+alterF :: forall k f v g. (GCompare  k, Functor f) => k v -> (Maybe (g v) -> f (Maybe (g v))) -> DMap k g -> f (DMap k g)
+alterF k f = go
+  where
+    go :: DMap k g -> f (DMap k g)
+    go Tip = maybe Tip (singleton k) <$> f Nothing
+
+    go (Bin sx kx x l r) = case gcompare k kx of
+      GLT -> (\l' -> balance kx x l' r) <$> go l
+      GGT -> (\r' -> balance kx x l r') <$> go r
+      GEQ -> maybe (glue l r) (\x' -> Bin sx kx x' l r) <$> f (Just x)
+
 {--------------------------------------------------------------------
   Indexing
 --------------------------------------------------------------------}
@@ -480,7 +491,7 @@
     go !idx (Bin _ kx _ l r)
       = case gcompare k kx of
           GLT -> go idx l
-          GGT -> go (idx + size l + 1) r 
+          GGT -> go (idx + size l + 1) r
           GEQ -> Just (idx + size l)
 
 -- | /O(log n)/. Retrieve an element by /index/. Calls 'error' when an
@@ -507,7 +518,7 @@
       EQ -> case f kx x of
               Just x' -> Bin sx kx x' l r
               Nothing -> glue l r
-      where 
+      where
         sizeL = size l
 
 -- | /O(log n)/. Delete the element at /index/.
@@ -584,7 +595,7 @@
     go Tip                 = Tip
 
 {--------------------------------------------------------------------
-  Union. 
+  Union.
 --------------------------------------------------------------------}
 
 -- | The union of a list of maps:
@@ -600,7 +611,7 @@
   = foldlStrict (unionWithKey f) empty ts
 
 -- | /O(m*log(n\/m + 1)), m <= n/.
--- The expression (@'union' t1 t2@) takes the left-biased union of @t1@ and @t2@. 
+-- The expression (@'union' t1 t2@) takes the left-biased union of @t1@ and @t2@.
 -- It prefers @t1@ when duplicate keys are encountered,
 -- i.e. (@'union' == 'unionWith' 'const'@).
 union :: GCompare k => DMap k f -> DMap k f -> DMap k f
@@ -635,7 +646,7 @@
   Difference
 --------------------------------------------------------------------}
 
--- | /O(m * log (n\/m + 1)), m <= n/. Difference of two maps. 
+-- | /O(m * log (n\/m + 1)), m <= n/. Difference of two maps.
 -- Return elements of the first map not existing in the second map.
 difference :: GCompare k => DMap k f -> DMap k g -> DMap k f
 difference Tip _   = Tip
@@ -651,7 +662,7 @@
 -- | /O(n+m)/. Difference with a combining function. When two equal keys are
 -- encountered, the combining function is applied to the key and both values.
 -- If it returns 'Nothing', the element is discarded (proper set difference). If
--- it returns (@'Just' y@), the element is updated with a new value @y@. 
+-- it returns (@'Just' y@), the element is updated with a new value @y@.
 differenceWithKey :: GCompare k => (forall v. k v -> f v -> g v -> Maybe (f v)) -> DMap k f -> DMap k g -> DMap k f
 differenceWithKey _ Tip _   = Tip
 differenceWithKey _ t1 Tip  = t1
@@ -702,8 +713,11 @@
 -- | /O(n+m)/.
 -- This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' 'eqTagged')@).
 --
-isSubmapOf :: (GCompare k, EqTag k f) => DMap k f -> DMap k f -> Bool
-isSubmapOf m1 m2 = isSubmapOfBy eqTagged m1 m2
+isSubmapOf
+  :: forall k f
+  .  (GCompare k, Has' Eq k f)
+  => DMap k f -> DMap k f -> Bool
+isSubmapOf m1 m2 = isSubmapOfBy (\k _ x0 x1 -> has' @Eq @f k (x0 == x1)) m1 m2
 
 {- | /O(n+m)/.
  The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if
@@ -724,17 +738,20 @@
   where
     (lt,found,gt) = splitLookupWithKey kx t
 
--- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal). 
+-- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal).
 -- Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy' 'eqTagged'@).
-isProperSubmapOf :: (GCompare k, EqTag k f) => DMap k f -> DMap k f -> Bool
+isProperSubmapOf
+  :: forall k f
+  .  (GCompare k, Has' Eq k f)
+  => DMap k f -> DMap k f -> Bool
 isProperSubmapOf m1 m2
-  = isProperSubmapOfBy eqTagged m1 m2
+  = isProperSubmapOfBy (\k _ x0 x1 -> has' @Eq @f k (x0 == x1)) m1 m2
 
 {- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal).
  The expression (@'isProperSubmapOfBy' f m1 m2@) returns 'True' when
  @m1@ and @m2@ are not equal,
  all keys in @m1@ are in @m2@, and when @f@ returns 'True' when
- applied to their respective keys and values. 
+ applied to their respective keys and values.
 -}
 isProperSubmapOfBy :: GCompare k => (forall v. k v -> k v -> f v -> g v -> Bool) -> DMap k f -> DMap k g -> Bool
 isProperSubmapOfBy f t1 t2
@@ -772,6 +789,10 @@
         (l1 :*: l2) = go p l
         (r1 :*: r2) = go p r
 
+-- | /O(n)/. Map values and collect the 'Just' results.
+mapMaybe :: GCompare k => (forall v. f v -> Maybe (g v)) -> DMap k f -> DMap k g
+mapMaybe f = mapMaybeWithKey (const f)
+
 -- | /O(n)/. Map keys\/values and collect the 'Just' results.
 mapMaybeWithKey :: GCompare k => (forall v. k v -> f v -> Maybe (g v)) -> DMap k f -> DMap k g
 mapMaybeWithKey f = go
@@ -808,6 +829,12 @@
     go Tip = Tip
     go (Bin sx kx x l r) = Bin sx kx (f x) (go l) (go r)
 
+-- | /O(n)/.
+-- @'ffor' == 'flip' 'map'@ except we cannot actually use
+-- 'flip' because of the lack of impredicative types.
+ffor :: DMap k f -> (forall v. f v -> g v) -> DMap k g
+ffor m f = map f m
+
 -- | /O(n)/. Map a function over all values in the map.
 mapWithKey :: (forall v. k v -> f v -> g v) -> DMap k f -> DMap k g
 mapWithKey f = go
@@ -816,9 +843,32 @@
     go (Bin sx kx x l r) = Bin sx kx (f kx x) (go l) (go r)
 
 -- | /O(n)/.
+-- @'fforWithKey' == 'flip' 'mapWithKey'@ except we cannot actually use
+-- 'flip' because of the lack of impredicative types.
+fforWithKey :: DMap k f -> (forall v. k v -> f v -> g v) -> DMap k g
+fforWithKey m f = mapWithKey f m
+
+-- | /O(n)/.
 -- @'traverseWithKey' f m == 'fromList' <$> 'traverse' (\(k, v) -> (,) k <$> f k v) ('toList' m)@
 -- That is, behaves exactly like a regular 'traverse' except that the traversing
 -- function also has access to the key associated with a value.
+traverseWithKey_ :: Applicative t => (forall v. k v -> f v -> t ()) -> DMap k f -> t ()
+traverseWithKey_ f = go
+  where
+    go Tip = pure ()
+    go (Bin 1 k v _ _) = f k v
+    go (Bin s k v l r) = go l *> f k v *> go r
+
+-- | /O(n)/.
+-- @'forWithKey' == 'flip' 'traverseWithKey'@ except we cannot actually use
+-- 'flip' because of the lack of impredicative types.
+forWithKey_ :: Applicative t => DMap k f -> (forall v. k v -> f v -> t ()) -> t ()
+forWithKey_ m f = traverseWithKey_ f m
+
+-- | /O(n)/.
+-- @'traverseWithKey' f m == 'fromList' <$> 'traverse' (\(k, v) -> (,) k <$> f k v) ('toList' m)@
+-- That is, behaves exactly like a regular 'traverse' except that the traversing
+-- function also has access to the key associated with a value.
 traverseWithKey :: Applicative t => (forall v. k v -> f v -> t (g v)) -> DMap k f -> t (DMap k g)
 traverseWithKey f = go
   where
@@ -826,8 +876,14 @@
     go (Bin 1 k v _ _) = (\v' -> Bin 1 k v' Tip Tip) <$> f k v
     go (Bin s k v l r) = flip (Bin s k) <$> go l <*> f k v <*> go r
 
+-- | /O(n)/.
+-- @'forWithKey' == 'flip' 'traverseWithKey'@ except we cannot actually use
+-- 'flip' because of the lack of impredicative types.
+forWithKey :: Applicative t => DMap k f -> (forall v. k v -> f v -> t (g v)) -> t (DMap k g)
+forWithKey m f = traverseWithKey f m
+
 -- | /O(n)/. The function 'mapAccumLWithKey' threads an accumulating
--- argument throught the map in ascending order of keys.
+-- argument through the map in ascending order of keys.
 mapAccumLWithKey :: (forall v. a -> k v -> f v -> (a, g v)) -> a -> DMap k f -> (a, DMap k g)
 mapAccumLWithKey f = go
   where
@@ -852,7 +908,7 @@
 
 -- | /O(n*log n)/.
 -- @'mapKeysWith' c f s@ is the map obtained by applying @f@ to each key of @s@.
--- 
+--
 -- The size of the result may be smaller if @f@ maps two or more distinct
 -- keys to the same new key.  In this case the associated values will be
 -- combined using @c@.
@@ -867,8 +923,8 @@
 -- That is, for any values @x@ and @y@, if @x@ < @y@ then @f x@ < @f y@.
 -- /The precondition is not checked./
 -- Semi-formally, we have:
--- 
--- > and [x < y ==> f x < f y | x <- ls, y <- ls] 
+--
+-- > and [x < y ==> f x < f y | x <- ls, y <- ls]
 -- >                     ==> mapKeysMonotonic f s == mapKeys f s
 -- >     where ls = keys s
 --
@@ -880,7 +936,7 @@
     Bin sz (f k) x (mapKeysMonotonic f l) (mapKeysMonotonic f r)
 
 {--------------------------------------------------------------------
-  Folds  
+  Folds
 --------------------------------------------------------------------}
 
 -- | /O(n)/. Fold the keys and values in the map, such that
@@ -918,7 +974,7 @@
 -}
 
 {--------------------------------------------------------------------
-  List variations 
+  List variations
 --------------------------------------------------------------------}
 
 -- | /O(n)/. Return all keys of the map in ascending order.
@@ -928,7 +984,7 @@
 
 keys  :: DMap k f -> [Some k]
 keys m
-  = [This k | (k :=> _) <- assocs m]
+  = [mkSome k | (k :=> _) <- assocs m]
 
 -- | /O(n)/. Return all key\/value pairs in the map in ascending key order.
 assocs :: DMap k f -> [DSum k f]
@@ -936,7 +992,7 @@
   = toList m
 
 {--------------------------------------------------------------------
-  Lists 
+  Lists
   use [foldlStrict] to reduce demand on the control-stack
 --------------------------------------------------------------------}
 
@@ -944,7 +1000,7 @@
 -- If the list contains more than one value for the same key, the last value
 -- for the key is retained.
 fromList :: GCompare k => [DSum k f] -> DMap k f
-fromList xs       
+fromList xs
   = foldlStrict ins empty xs
   where
     ins :: GCompare k => DMap k f -> DSum k f -> DMap k f
@@ -952,7 +1008,7 @@
 
 -- | /O(n*log n)/. Build a map from a list of key\/value pairs with a combining function. See also 'fromAscListWithKey'.
 fromListWithKey :: GCompare k => (forall v. k v -> f v -> f v -> f v) -> [DSum k f] -> DMap k f
-fromListWithKey f xs 
+fromListWithKey f xs
   = foldlStrict (ins f) empty xs
   where
     ins :: GCompare k => (forall v. k v -> f v -> f v -> f v) -> DMap k f -> DSum k f -> DMap k f
@@ -972,8 +1028,8 @@
 
 {--------------------------------------------------------------------
   Building trees from ascending/descending lists can be done in linear time.
-  
-  Note that if [xs] is ascending that: 
+
+  Note that if [xs] is ascending that:
     fromAscList xs       == fromList xs
     fromAscListWith f xs == fromListWith f xs
 --------------------------------------------------------------------}
@@ -987,7 +1043,7 @@
 -- | /O(n)/. Build a map from an ascending list in linear time with a
 -- combining function for equal keys.
 -- /The precondition (input list is ascending) is not checked./
-fromAscListWithKey :: GEq k => (forall v. k v -> f v -> f v -> f v) -> [DSum k f] -> DMap k f 
+fromAscListWithKey :: GEq k => (forall v. k v -> f v -> f v -> f v) -> [DSum k f] -> DMap k f
 fromAscListWithKey f xs
   = fromDistinctAscList (combineEq f xs)
   where
@@ -1013,12 +1069,12 @@
   = build const (length xs) xs
   where
     -- 1) use continutations so that we use heap space instead of stack space.
-    -- 2) special case for n==5 to build bushier trees. 
-    
+    -- 2) special case for n==5 to build bushier trees.
+
     build :: (DMap k f -> [DSum k f] -> b) -> Int -> [DSum k f] -> b
     build c 0 xs'  = c Tip xs'
     build c 5 xs'  = case xs' of
-                       ((k1:=>x1):(k2:=>x2):(k3:=>x3):(k4:=>x4):(k5:=>x5):xx) 
+                       ((k1:=>x1):(k2:=>x2):(k3:=>x3):(k4:=>x4):(k5:=>x5):xx)
                             -> c (bin k4 x4 (bin k2 x2 (singleton k1 x1) (singleton k3 x3)) (singleton k5 x5)) xx
                        _ -> error "fromDistinctAscList build"
     build c n xs'  = seq nr $ build (buildR nr c) nl xs'
@@ -1029,10 +1085,10 @@
     buildR :: Int -> (DMap k f -> [DSum k f] -> b) -> DMap k f -> [DSum k f] -> b
     buildR n c l ((k:=>x):ys) = build (buildB l k x c) n ys
     buildR _ _ _ []           = error "fromDistinctAscList buildR []"
-    
+
     buildB :: DMap k f -> k v -> f v -> (DMap k f -> a -> b) -> DMap k f -> a -> b
     buildB l k x c r zs       = c (bin k x l r) zs
-                      
+
 {--------------------------------------------------------------------
   Split
 --------------------------------------------------------------------}
@@ -1087,25 +1143,25 @@
       GEQ -> Triple' l (Just (kx, x)) r
 
 {--------------------------------------------------------------------
-  Eq converts the tree to a list. In a lazy setting, this 
-  actually seems one of the faster methods to compare two trees 
+  Eq converts the tree to a list. In a lazy setting, this
+  actually seems one of the faster methods to compare two trees
   and it is certainly the simplest :-)
 --------------------------------------------------------------------}
-instance EqTag k f => Eq (DMap k f) where
+instance (GEq k, Has' Eq k f) => Eq (DMap k f) where
   t1 == t2  = (size t1 == size t2) && (toAscList t1 == toAscList t2)
 
 {--------------------------------------------------------------------
-  Ord 
+  Ord
 --------------------------------------------------------------------}
 
-instance OrdTag k f => Ord (DMap k f) where
-    compare m1 m2 = compare (toAscList m1) (toAscList m2)
+instance (GCompare k, Has' Eq k f, Has' Ord k f) => Ord (DMap k f) where
+  compare m1 m2 = compare (toAscList m1) (toAscList m2)
 
 {--------------------------------------------------------------------
   Read
 --------------------------------------------------------------------}
 
-instance (GCompare k, ReadTag k f) => Read (DMap k f) where
+instance (GCompare k, GRead k, Has' Read k f) => Read (DMap k f) where
   readPrec = parens $ prec 10 $ do
     Ident "fromList" <- lexP
     xs <- readPrec
@@ -1116,7 +1172,7 @@
 {--------------------------------------------------------------------
   Show
 --------------------------------------------------------------------}
-instance ShowTag k f => Show (DMap k f) where
+instance (GShow k, Has' Show k f) => Show (DMap k f) where
     showsPrec p m = showParen (p>10)
         ( showString "fromList "
         . showsPrec 11 (toList m)
@@ -1124,11 +1180,11 @@
 
 -- | /O(n)/. Show the tree that implements the map. The tree is shown
 -- in a compressed, hanging format. See 'showTreeWith'.
-showTree :: ShowTag k f => DMap k f -> String
+showTree :: (GShow k, Has' Show k f) => DMap k f -> String
 showTree m
   = showTreeWith showElem True False m
   where
-    showElem :: ShowTag k f => k v -> f v -> String
+    showElem :: (GShow k, Has' Show k f) => k v -> f v -> String
     showElem k x  = show (k :=> x)
 
 
@@ -1147,7 +1203,7 @@
   = case t of
       Tip -> showsBars lbars . showString "|\n"
       Bin _ kx x Tip Tip
-          -> showsBars lbars . showString (showelem kx x) . showString "\n" 
+          -> showsBars lbars . showString (showelem kx x) . showString "\n"
       Bin _ kx x l r
           -> showsTree showelem wide (withBar rbars) (withEmpty rbars) r .
              showWide wide rbars .
@@ -1158,19 +1214,19 @@
 showsTreeHang :: (forall v. k v -> f v -> String) -> Bool -> [String] -> DMap k f -> ShowS
 showsTreeHang showelem wide bars t
   = case t of
-      Tip -> showsBars bars . showString "|\n" 
+      Tip -> showsBars bars . showString "|\n"
       Bin _ kx x Tip Tip
-          -> showsBars bars . showString (showelem kx x) . showString "\n" 
+          -> showsBars bars . showString (showelem kx x) . showString "\n"
       Bin _ kx x l r
-          -> showsBars bars . showString (showelem kx x) . showString "\n" . 
+          -> showsBars bars . showString (showelem kx x) . showString "\n" .
              showWide wide bars .
              showsTreeHang showelem wide (withBar bars) l .
              showWide wide bars .
              showsTreeHang showelem wide (withEmpty bars) r
 
 showWide :: Bool -> [String] -> String -> String
-showWide wide bars 
-  | wide      = showString (concat (reverse bars)) . showString "|\n" 
+showWide wide bars
+  | wide      = showString (concat (reverse bars)) . showString "|\n"
   | otherwise = id
 
 showsBars :: [String] -> ShowS
@@ -1203,7 +1259,7 @@
     bounded lo hi t'
       = case t' of
           Tip              -> True
-          Bin _ kx _ l r  -> (lo (This kx)) && (hi (This kx)) && bounded lo (< This kx) l && bounded (> This kx) hi r
+          Bin _ kx _ l r  -> lo (mkSome kx) && hi (mkSome kx) && bounded lo (< mkSome kx) l && bounded (> mkSome kx) hi r
 
 -- | Exported only for "Debug.QuickCheck"
 balanced :: DMap k f -> Bool
@@ -1231,4 +1287,3 @@
   where
     go z []     = z
     go z (x:xs) = z `seq` go (f z x) xs
-
diff --git a/src/Data/Dependent/Map/Internal.hs b/src/Data/Dependent/Map/Internal.hs
--- a/src/Data/Dependent/Map/Internal.hs
+++ b/src/Data/Dependent/Map/Internal.hs
@@ -1,28 +1,21 @@
-{-# LANGUAGE GADTs #-}
+{-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE Safe #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE CPP #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Safe #-}
-#endif
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
-{-# LANGUAGE PolyKinds #-}
-#endif
 module Data.Dependent.Map.Internal where
 
-import Data.Dependent.Sum
-import Data.GADT.Compare
-import Data.Some
-#if MIN_VERSION_base(4,7,0)
+import Data.Dependent.Sum (DSum((:=>)))
+import Data.GADT.Compare (GCompare, GOrdering(..), gcompare)
+import Data.Some (Some, mkSome, withSome)
 import Data.Typeable (Typeable)
-#endif
 
--- |Dependent maps: 'k' is a GADT-like thing with a facility for 
+-- |Dependent maps: 'k' is a GADT-like thing with a facility for
 -- rediscovering its type parameter, elements of which function as identifiers
 -- tagged with the type of the thing they identify.  Real GADTs are one
--- useful instantiation of @k@, as are 'Tag's from "Data.Unique.Tag" in the 
+-- useful instantiation of @k@, as are 'Tag's from "Data.Unique.Tag" in the
 -- 'prim-uniq' package.
 --
 -- Semantically, @'DMap' k f@ is equivalent to a set of @'DSum' k f@ where no two
@@ -39,9 +32,7 @@
         -> {- left  -} !(DMap k f)
         -> {- right -} !(DMap k f)
         -> DMap k f
-#if MIN_VERSION_base(4,7,0)
     deriving Typeable
-#endif
 
 {--------------------------------------------------------------------
   Construction
@@ -84,15 +75,15 @@
     where
         go :: DMap k f -> Maybe (f v)
         go Tip = Nothing
-        go (Bin _ kx x l r) = 
+        go (Bin _ kx x l r) =
             case gcompare k kx of
                 GLT -> go l
                 GGT -> go r
                 GEQ -> Just x
 
 lookupAssoc :: forall k f v. GCompare k => Some k -> DMap k f -> Maybe (DSum k f)
-lookupAssoc (This k) = k `seq` go
-  where
+lookupAssoc sk = withSome sk $ \k ->
+  let
     go :: DMap k f -> Maybe (DSum k f)
     go Tip = Nothing
     go (Bin _ kx x l r) =
@@ -100,12 +91,13 @@
             GLT -> go l
             GGT -> go r
             GEQ -> Just (kx :=> x)
+  in k `seq` go
 
 {--------------------------------------------------------------------
   Utility functions that maintain the balance properties of the tree.
   All constructors assume that all values in [l] < [k] and all values
   in [r] > [k], and that [l] and [r] are valid trees.
-  
+
   In order of sophistication:
     [Bin sz k x l r]  The type constructor.
     [bin k x l r]     Maintains the correct size, assumes that both [l]
@@ -113,7 +105,7 @@
     [balance k x l r] Restores the balance and size.
                       Assumes that the original tree was balanced and
                       that [l] or [r] has changed by at most one element.
-    [combine k x l r] Restores balance and size. 
+    [combine k x l r] Restores balance and size.
 
   Furthermore, we can construct a new tree from two trees. Both operations
   assume that all values in [l] < all values in [r] and that [l] and [r]
@@ -123,10 +115,10 @@
     [merge l r]       Merges two trees and restores balance.
 
   Note: in contrast to Adam's paper, we use (<=) comparisons instead
-  of (<) comparisons in [combine], [merge] and [balance]. 
-  Quickcheck (on [difference]) showed that this was necessary in order 
-  to maintain the invariants. It is quite unsatisfactory that I haven't 
-  been able to find out why this is actually the case! Fortunately, it 
+  of (<) comparisons in [combine], [merge] and [balance].
+  Quickcheck (on [difference]) showed that this was necessary in order
+  to maintain the invariants. It is quite unsatisfactory that I haven't
+  been able to find out why this is actually the case! Fortunately, it
   doesn't hurt to be a bit more conservative.
 --------------------------------------------------------------------}
 
@@ -149,13 +141,13 @@
       Tip -> singleton kx x
       Bin _ ky y l r
           -> balance ky y l (insertMax kx x r)
-             
+
 insertMin kx x t
   = case t of
       Tip -> singleton kx x
       Bin _ ky y l r
           -> balance ky y (insertMin kx x l) r
-             
+
 {--------------------------------------------------------------------
   [merge l r]: merges two trees.
 --------------------------------------------------------------------}
@@ -174,13 +166,13 @@
 glue :: DMap k f -> DMap k f -> DMap k f
 glue Tip r = r
 glue l Tip = l
-glue l r   
+glue l r
   | size l > size r = case deleteFindMax l of (km :=> m,l') -> balance km m l' r
   | otherwise       = case deleteFindMin r of (km :=> m,r') -> balance km m l r'
 
 -- | /O(log n)/. Delete and find the minimal element.
 --
--- > deleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")]) 
+-- > deleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
 -- > deleteFindMin                                            Error: can not return the minimal element of an empty map
 
 deleteFindMin :: DMap k f -> (DSum k f, DMap k f)
@@ -251,13 +243,13 @@
   [ratio] is the ratio between an outer and inner sibling of the
           heavier subtree in an unbalanced setting. It determines
           whether a double or single rotation should be performed
-          to restore balance. It is correspondes with the inverse
+          to restore balance. It corresponds with the inverse
           of $\alpha$ in Adam's article.
 
   Note that:
   - [delta] should be larger than 4.646 with a [ratio] of 2.
   - [delta] should be larger than 3.745 with a [ratio] of 1.534.
-  
+
   - A lower [delta] leads to a more 'perfectly' balanced tree.
   - A higher [delta] performs less rebalancing.
 
@@ -267,7 +259,7 @@
     [delta] may perform better than smaller one.
 
   Note: in contrast to Adam's paper, we use a ratio of (at least) [2]
-  to decide whether a single or double rotation is needed. Allthough
+  to decide whether a single or double rotation is needed. Although
   he actually proves that this ratio is needed to maintain the
   invariants, his implementation uses an invalid ratio of [1].
 --------------------------------------------------------------------}
@@ -344,17 +336,17 @@
 trim :: (Some k -> Ordering) -> (Some k -> Ordering) -> DMap k f -> DMap k f
 trim _     _     Tip = Tip
 trim cmplo cmphi t@(Bin _ kx _ l r)
-  = case cmplo (This kx) of
-      LT -> case cmphi (This kx) of
+  = case cmplo (mkSome kx) of
+      LT -> case cmphi (mkSome kx) of
               GT -> t
               _  -> trim cmplo cmphi l
       _  -> trim cmplo cmphi r
-              
+
 trimLookupLo :: GCompare k => Some k -> (Some k -> Ordering) -> DMap k f -> (Maybe (DSum k f), DMap k f)
 trimLookupLo _  _     Tip = (Nothing,Tip)
 trimLookupLo lo cmphi t@(Bin _ kx x l r)
-  = case compare lo (This kx) of
-      LT -> case cmphi (This kx) of
+  = case compare lo (mkSome kx) of
+      LT -> case cmphi (mkSome kx) of
               GT -> (lookupAssoc lo t, t)
               _  -> trimLookupLo lo cmphi l
       GT -> trimLookupLo lo cmphi r
@@ -369,7 +361,7 @@
 filterGt cmp = go
   where
     go Tip              = Tip
-    go (Bin _ kx x l r) = case cmp (This kx) of
+    go (Bin _ kx x l r) = case cmp (mkSome kx) of
               LT -> combine kx x (go l) r
               GT -> go r
               EQ -> r
@@ -378,7 +370,7 @@
 filterLt cmp = go
   where
     go Tip              = Tip
-    go (Bin _ kx x l r) = case cmp (This kx) of
+    go (Bin _ kx x l r) = case cmp (mkSome kx) of
           LT -> go l
           GT -> combine kx x l (go r)
           EQ -> l
diff --git a/src/Data/Dependent/Map/Lens.hs b/src/Data/Dependent/Map/Lens.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Dependent/Map/Lens.hs
@@ -0,0 +1,83 @@
+{-# LANGUAGE PolyKinds #-}
+-- |
+-- Some functions for using lenses with 'DMap'.
+module Data.Dependent.Map.Lens
+  ( -- * At
+    dmat
+    -- * Ix
+  , dmix
+  )
+  where
+
+import           Prelude             hiding (lookup)
+
+import           Data.Dependent.Map  (DMap, alterF, insert, lookup)
+
+import           Data.GADT.Compare   (GCompare)
+
+-- |
+-- These functions have been specialised for use with 'DMap' but without any of the
+-- specific 'lens' types used so that we have compatibility without needing the
+-- dependency just for these functions.
+--
+
+-- |
+-- This is equivalent to the <https://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-At.html#v:at at> <https://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-Type.html#t:Lens-39- Lens'> from <https://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-At.html Control.Lens.At>:
+--
+-- @
+-- type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
+--
+-- at :: Index m -> Lens' m (Maybe (IxValue m))
+-- @
+--
+-- So the type of 'dmat' is equivalent to:
+--
+-- @
+-- dmat :: GCompare k => Lens' (DMap k f) (Maybe (f v))
+-- @
+--
+-- >>> DMap.fromList [AInt :=> Identity 33, AFloat :=> Identity 3.5] & dmat AString ?~ "Hat"
+-- DMap.fromList [AString :=> Identity "Hat", AInt :=> Identity 33, AFloat :=> Identity 3.5]
+--
+-- >>> DMap.fromList [AString :=> Identity "Shoe", AInt :=> Identity 33, AFloat :=> Identity 3.5] ^? dmat AFloat
+-- Just (AFloat :=> 3.5)
+--
+dmat :: (GCompare k, Functor f) => k v -> (Maybe (g v) -> f (Maybe (g v))) -> DMap k g -> f (DMap k g)
+dmat k f = alterF k f
+{-# INLINE dmat #-}
+
+-- |
+-- This is equivalent to the <https://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-At.html#v:ix ix> <https://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-Type.html#t:Traversal-39- Traversal'> from <https://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-At.html Control.Lens.At>:
+--
+-- @
+-- type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t
+--
+-- ix :: Index m -> Traversal' m (IxValue m)
+-- @
+--
+-- So the type of 'dmix' is equivalent to:
+--
+-- @
+-- dmix :: GCompare k => k v -> Traversal' (DMap k f) (f v)
+-- @
+--
+-- /NB:/ Setting the value of this
+-- <https://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-Type.html#t:Traversal Traversal>
+-- will only set the value in 'dmix' if it is already present.
+--
+-- If you want to be able to insert /missing/ values, you want 'dmat'.
+--
+-- >>> DMap.fromList [AString :=> Identity "Shoe", AInt :=> Identity 33, AFloat :=> Identity 3.5] & dmix AInt %~ f
+-- DMap.fromList [AString :=> Identity "Shoe", AInt :=> Identity (f 33), AFloat :=> Identity 3.5]
+--
+-- >>> DMap.fromList [AString :=> Identity "Shoe", AInt :=> Identity 33, AFloat :=> Identity 3.5] & dmix AString .~ "Hat"
+-- DMap.fromList [AString :=> Identity "Hat", AInt :=> Identity 33, AFloat :=> Identity 3.5]
+--
+-- >>> DMap.fromList [AString :=> Identity "Shoe", AInt :=> Identity 33, AFloat :=> Identity 3.5] ^? dmix AFloat
+-- Just (AFloat :=> 3.5)
+--
+-- >>> DMap.fromList [AString :=> Identity "Shoe", AFloat :=> Identity 3.5] ^? dmix AInt
+-- Nothing
+dmix :: (GCompare k, Applicative f) => k v -> (g v -> f (g v)) -> DMap k g -> f (DMap k g)
+dmix k f dmap = maybe (pure dmap) (fmap (flip (insert k) dmap) . f) $ lookup k dmap
+{-# INLINE dmix #-}
diff --git a/src/Data/Dependent/Map/PtrEquality.hs b/src/Data/Dependent/Map/PtrEquality.hs
--- a/src/Data/Dependent/Map/PtrEquality.hs
+++ b/src/Data/Dependent/Map/PtrEquality.hs
@@ -1,7 +1,4 @@
-{-# LANGUAGE CPP #-}
-#ifdef __GLASGOW_HASKELL__
 {-# LANGUAGE MagicHash #-}
-#endif
 
 {-# OPTIONS_HADDOCK hide #-}
 
@@ -13,7 +10,7 @@
 --
 -- The Package Versioning Policy __does not apply__.
 --
--- This contents of this module may change __in any way whatsoever__
+-- The contents of this module may change __in any way whatsoever__
 -- and __without any warning__ between minor versions of this package.
 --
 -- Authors importing this module are expected to track development
@@ -21,16 +18,10 @@
 
 module Data.Dependent.Map.PtrEquality (ptrEq, hetPtrEq) where
 
-#ifdef __GLASGOW_HASKELL__
-import GHC.Exts ( reallyUnsafePtrEquality# )
-import Unsafe.Coerce ( unsafeCoerce )
-#if __GLASGOW_HASKELL__ < 707
-import GHC.Exts ( (==#) )
-#else
-import GHC.Exts ( isTrue# )
-#endif
-#endif
+import Unsafe.Coerce (unsafeCoerce)
+import GHC.Exts (isTrue#, reallyUnsafePtrEquality#)
 
+
 -- | Checks if two pointers are equal. Yes means yes;
 -- no means maybe. The values should be forced to at least
 -- WHNF before comparison to get moderately reliable results.
@@ -42,20 +33,8 @@
 -- reliable results.
 hetPtrEq :: a -> b -> Bool
 
-#ifdef __GLASGOW_HASKELL__
-#if __GLASGOW_HASKELL__ < 707
-ptrEq x y = reallyUnsafePtrEquality# x y ==# 1#
-hetPtrEq x y = unsafeCoerce reallyUnsafePtrEquality# x y ==# 1#
-#else
 ptrEq x y = isTrue# (reallyUnsafePtrEquality# x y)
 hetPtrEq x y = isTrue# (unsafeCoerce reallyUnsafePtrEquality# x y)
-#endif
-
-#else
--- Not GHC
-ptrEq _ _ = False
-hetPtrEq _ _ = False
-#endif
 
 {-# INLINE ptrEq #-}
 {-# INLINE hetPtrEq #-}
diff --git a/src/Data/Dependent/Map/Typeable.hs b/src/Data/Dependent/Map/Typeable.hs
deleted file mode 100644
--- a/src/Data/Dependent/Map/Typeable.hs
+++ /dev/null
@@ -1,21 +0,0 @@
-{-# LANGUAGE CPP #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Trustworthy #-}
-#endif
-module Data.Dependent.Map.Typeable where
-
-import Data.Dependent.Map.Internal
-import Data.Typeable
-
-instance (Typeable1 k, Typeable1 f) => Typeable (DMap k f) where
-    typeOf ds = mkTyConApp dMapCon [typeOfK, typeOfF]
-        where
-            typeOfK = typeOf1 $ (undefined :: DMap k f -> k a) ds
-            typeOfF = typeOf1 $ (undefined :: DMap k f -> f a) ds
-            
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-            dMapCon = mkTyCon3 "dependent-map" "Data.Dependent.Map" "DMap"
-#else
-            dMapCon = mkTyCon "Data.Dependent.Map.DMap"
-
-#endif
