diff --git a/primitive-containers.cabal b/primitive-containers.cabal
--- a/primitive-containers.cabal
+++ b/primitive-containers.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.0
 name: primitive-containers
-version: 0.3.1
+version: 0.3.2
 synopsis: containers backed by arrays
 description:
   Containers backed by flat arrays. Updates require rebuilding the
@@ -107,13 +107,13 @@
   build-depends:
       base
     , HUnit
-    , QuickCheck < 2.12
+    , QuickCheck < 2.13
     , aeson
     , containers >= 0.5.10
     , primitive
     , primitive-containers
     , quantification >= 0.4
-    , quickcheck-classes >= 0.5
+    , quickcheck-classes >= 0.6
     , tasty
     , tasty-hunit
     , tasty-quickcheck
diff --git a/src/Data/Map/Internal.hs b/src/Data/Map/Internal.hs
--- a/src/Data/Map/Internal.hs
+++ b/src/Data/Map/Internal.hs
@@ -214,7 +214,10 @@
   go 1 k0 n keys0 vals0 xs0
 
 
-map :: (Contiguous varr, Element varr v, Element varr w) => (v -> w) -> Map karr varr k v -> Map karr varr k w
+map :: (Contiguous varr, Contiguous warr, Element varr v, Element warr w)
+  => (v -> w)
+  -> Map karr varr k v
+  -> Map karr warr k w
 map f (Map k v) = Map k (I.map f v)
 
 -- | /O(n)/ Map over the elements with access to their corresponding keys.
diff --git a/src/Data/Map/Interval/DBTS/Internal.hs b/src/Data/Map/Interval/DBTS/Internal.hs
--- a/src/Data/Map/Interval/DBTS/Internal.hs
+++ b/src/Data/Map/Interval/DBTS/Internal.hs
@@ -22,11 +22,13 @@
   , foldrWithKey
   , foldlWithKeyM'
   , foldl'
+  , foldlM'
   , foldMap
   , toList
   , showsPrec
   , concat
   , elems
+  , size
   ) where
 
 import Prelude hiding (pure,lookup,compare,map,showsPrec,concat,traverse,foldMap)
@@ -346,6 +348,13 @@
   -> b
 foldl' f b0 (Map _ vals) = I.foldl' f b0 vals
 
+foldlM' :: (Contiguous varr, Element varr v, Monad m)
+  => (b -> v -> m b)
+  -> b
+  -> Map karr varr k v
+  -> m b
+foldlM' f b0 (Map _ vals) = I.foldlM' f b0 vals
+
 foldMap :: (Contiguous varr, Element varr v, Monoid m)
   => (v -> m)
   -> Map karr varr k v
@@ -380,4 +389,3 @@
 
 elems :: Map karr varr k v -> varr v
 elems (Map _ v) = v
-
diff --git a/src/Data/Map/Interval/DBTSLL.hs b/src/Data/Map/Interval/DBTSLL.hs
--- a/src/Data/Map/Interval/DBTSLL.hs
+++ b/src/Data/Map/Interval/DBTSLL.hs
@@ -20,12 +20,16 @@
   , traverseBijection
     -- * Folds
   , foldl'
+  , foldlM'
   , foldMap
   , foldrWithKey
   , foldlWithKeyM'
   , traverse_
+    -- * Properties
+  , size
     -- * Conversion
   , elems
+  , toList
   ) where
 
 import Prelude hiding (lookup,map,pure,foldMap)
@@ -116,6 +120,13 @@
   -> b
 foldl' f b0 (Map m) = I.foldl' f b0 m
 
+foldlM' :: Monad m
+  => (b -> v -> m b)
+  -> b
+  -> Map k v
+  -> m b
+foldlM' f b0 (Map m) = I.foldlM' f b0 m
+
 foldMap :: (Monoid m)
   => (v -> m)
   -> Map k v
@@ -143,6 +154,13 @@
   -> m b
 foldlWithKeyM' f z (Map m) = I.foldlWithKeyM' f z m
 
+-- | The number of values in the interval map. Also the number of
+--   contiguous key ranges in the map.
+size :: Map k v -> Int
+size (Map m) = I.size m
+
 elems :: Map k v -> Array v
 elems (Map m) = I.elems m
 
+toList :: (Bounded k, Enum k) => Map k v -> [(k,k,v)]
+toList (Map m) = I.toList m
diff --git a/src/Data/Map/Unboxed/Lifted.hs b/src/Data/Map/Unboxed/Lifted.hs
--- a/src/Data/Map/Unboxed/Lifted.hs
+++ b/src/Data/Map/Unboxed/Lifted.hs
@@ -5,7 +5,7 @@
 
 {-# OPTIONS_GHC -O2 #-}
 module Data.Map.Unboxed.Lifted
-  ( Map
+  ( Map(..) -- TODO: use an internal module for this
   , empty
   , singleton
   , lookup
diff --git a/src/Data/Map/Unboxed/Unlifted.hs b/src/Data/Map/Unboxed/Unlifted.hs
--- a/src/Data/Map/Unboxed/Unlifted.hs
+++ b/src/Data/Map/Unboxed/Unlifted.hs
@@ -12,6 +12,7 @@
   , size
     -- * Transform
   , map
+  , mapLifted
   , mapMaybe
   , mapMaybeP
   , mapMaybeWithKey
@@ -19,6 +20,7 @@
     -- * Folds
   , foldlWithKey'
   , foldrWithKey'
+  , foldMapWithKey
   , foldMapWithKey'
     -- * Monadic Folds
   , foldlWithKeyM'
@@ -48,6 +50,7 @@
 import Data.Semigroup (Semigroup)
 import Data.Set.Unboxed.Internal (Set(..))
 
+import qualified Data.Map.Unboxed.Lifted as MUL
 import qualified Data.Map.Internal as I
 import qualified Data.Semigroup as SG
 import qualified GHC.Exts as E
@@ -157,6 +160,14 @@
   -> Map k w
 map f (Map m) = Map (I.map f m)
 
+-- | /O(n)/ Map over the values in the map. The resulting map contains
+--   lifted values.
+mapLifted :: (Prim k, PrimUnlifted v)
+  => (v -> w)
+  -> Map k v
+  -> MUL.Map k w
+mapLifted f (Map m) = MUL.Map (I.map f m)
+
 -- | /O(n)/ Drop elements for which the predicate returns 'Nothing'.
 mapMaybe :: (Prim k, PrimUnlifted v, PrimUnlifted w)
   => (v -> Maybe w)
@@ -242,6 +253,16 @@
   -> Map k v
   -> m (Map k w)
 traverse f (Map m) = fmap Map (I.traverse f m)
+
+-- | /O(n)/ Fold over the keys and values of the map with a monoidal
+-- accumulator. This function does not have left and right variants since
+-- the associativity required by a monoid instance means that both variants
+-- would always produce the same result.
+foldMapWithKey :: (Monoid b, Prim k, PrimUnlifted v)
+  => (k -> v -> b) -- ^ reduction 
+  -> Map k v -- ^ map
+  -> b
+foldMapWithKey f (Map m) = I.foldMapWithKey f m
 
 -- | /O(n)/ Fold over the keys and values of the map with a strict monoidal
 -- accumulator. This function does not have left and right variants since
diff --git a/src/Data/Set/Internal.hs b/src/Data/Set/Internal.hs
--- a/src/Data/Set/Internal.hs
+++ b/src/Data/Set/Internal.hs
@@ -17,6 +17,7 @@
   , tripleton
   , difference
   , intersection
+  , intersects
   , append
   , member
   , showsPrec
@@ -150,6 +151,32 @@
   where
     !sz1 = size s1
     !sz2 = size s2
+
+intersects :: forall a arr. (Contiguous arr, Element arr a, Ord a)
+  => Set arr a
+  -> Set arr a
+  -> Bool
+intersects s1 s2
+  | sz1 == 0 = False
+  | sz2 == 0 = False
+  | otherwise =
+      let (smaller@(Set arr1),larger@(Set arr2)) = if sz1 <= sz2
+            then (s1,s2)
+            else (s2,s1)
+          !szSmaller = size smaller
+          go :: Int -> ST s Bool
+          go !ix = if ix < szSmaller
+            then do
+              v <- A.indexM arr1 ix
+              if member v larger
+                then return True
+                else go (ix + 1)
+            else return False
+      in runST (go 0)
+  where
+    !sz1 = size s1
+    !sz2 = size s2
+{-# INLINEABLE intersects #-}
 
 intersection :: forall a arr. (Contiguous arr, Element arr a, Ord a)
   => Set arr a
diff --git a/src/Data/Set/Lifted.hs b/src/Data/Set/Lifted.hs
--- a/src/Data/Set/Lifted.hs
+++ b/src/Data/Set/Lifted.hs
@@ -15,6 +15,7 @@
   , (\\)
   , intersection
   , subset
+  , intersects
     -- * Conversion
   , toArray
   , LI.toList
@@ -44,6 +45,10 @@
 -- | The intersection of two sets.
 intersection :: Ord a => Set a -> Set a -> Set a
 intersection (Set x) (Set y) = Set (I.intersection x y)
+
+-- | Do the two sets contain any of the same elements?
+intersects :: Ord a => Set a -> Set a -> Bool
+intersects (Set x) (Set y) = I.intersects x y
 
 -- | Is the first argument a subset of the second argument?
 subset :: Ord a => Set a -> Set a -> Bool
diff --git a/src/Data/Set/Unboxed.hs b/src/Data/Set/Unboxed.hs
--- a/src/Data/Set/Unboxed.hs
+++ b/src/Data/Set/Unboxed.hs
@@ -18,6 +18,7 @@
   , (\\)
   , intersection
   , subset
+  , intersects
   , enumFromTo
     -- * List Conversion
   , S.toList
@@ -64,6 +65,10 @@
 -- | The intersection of two sets.
 intersection :: (Ord a, Prim a) => Set a -> Set a -> Set a
 intersection (Set x) (Set y) = Set (I.intersection x y)
+
+-- | Do the two sets contain any of the same elements?
+intersects :: (Ord a, Prim a) => Set a -> Set a -> Bool
+intersects (Set x) (Set y) = I.intersects x y
 
 -- | Is the first argument a subset of the second argument?
 subset :: (Ord a, Prim a) => Set a -> Set a -> Bool
diff --git a/src/Data/Set/Unlifted.hs b/src/Data/Set/Unlifted.hs
--- a/src/Data/Set/Unlifted.hs
+++ b/src/Data/Set/Unlifted.hs
@@ -5,6 +5,7 @@
 {-# LANGUAGE TypeFamilies #-}
 
 {-# OPTIONS_GHC -O2 #-}
+
 module Data.Set.Unlifted
   ( S.Set
   , empty
@@ -14,6 +15,8 @@
   , size
   , difference
   , intersection
+  , intersects
+  , subset
   , enumFromTo
     -- * Conversion
   , toArray
@@ -65,6 +68,14 @@
 -- | The intersection of two sets.
 intersection :: (Ord a, PrimUnlifted a) => Set a -> Set a -> Set a
 intersection (Set x) (Set y) = Set (I.intersection x y)
+
+-- | Do the two sets contain any of the same elements?
+intersects :: (Ord a, PrimUnlifted a) => Set a -> Set a -> Bool
+intersects (Set x) (Set y) = I.intersects x y
+
+-- | Is the first argument a subset of the second argument?
+subset :: (Ord a, PrimUnlifted a) => Set a -> Set a -> Bool
+subset (Set x) (Set y) = I.subset x y
 
 -- | The set that includes all elements from the lower bound to the
 -- upper bound.
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -84,6 +84,7 @@
       , lawsToTest (QCC.isListLaws (Proxy :: Proxy (SU.Set Int16)))
       , TQC.testProperty "member" (memberProp @Int16 E.fromList SU.member)
       , TQC.testProperty "tripleton" setTripletonProp
+      , TQC.testProperty "intersects" intersectsWorksProp
       ]
     , testGroup "Lifted"
       [ lawsToTest (QCC.eqLaws (Proxy :: Proxy (SL.Set Integer)))
@@ -538,6 +539,17 @@
 dietValidProp = QC.property $ \(xs :: DMLL.Map Word8 Int) ->
   True === validDietTriples (E.toList xs)
 
+intersectsSet :: Ord a => S.Set a -> S.Set a -> Bool
+intersectsSet s1 s2 =
+  let s3 = s1 <> s2
+  in if length s3 == length s1 + length s2
+    then False
+    else True
+
+intersectsWorksProp :: QC.Property
+intersectsWorksProp = QC.property $ \(xs :: S.Set Int) (ys :: S.Set Int) ->
+  intersectsSet xs ys == SU.intersects (SU.fromList (S.toList xs)) (SU.fromList (S.toList ys))
+
 simpleDoubletonToList :: (Ord k, Enum k, Semigroup v, Eq v) => k -> k -> v -> k -> k -> v -> [(k,k,v)]
 simpleDoubletonToList key1A key2A valA key1B key2B valB =
   let loA = min key1A key2A
@@ -963,4 +975,5 @@
   writeOffAddrForall# = writeOffAddr#
   indexOffAddrForall# = indexOffAddr#
   setOffAddrForall# = setOffAddr#
+
 
