diff --git a/multimap.cabal b/multimap.cabal
--- a/multimap.cabal
+++ b/multimap.cabal
@@ -1,10 +1,16 @@
 Name:           multimap
-Version:        1.1
+Version:        1.2
 Synopsis:       A multimap.
 Description:    This is a simple implementation of a multimap, based on "Data.Map".
                 .
-                [@v1.1@] @!@ had its arguments flipped. Fixed.
+                [@v1.1@]
+                    @!@ had its arguments flipped. Fixed.
                     Also added @fromMap@.
+                .
+                [@v1.2]
+                    Added "Data.SetMap", renamed @Multimap@ to "Data.MultiMap".
+                    Fixed the type of @delete@. Derive instances for @Data@
+                    and @Typeable@.
                 
 License:        MIT
 License-File:   LICENSE
@@ -21,7 +27,8 @@
     location: hub.darcs.net:multimap
 
 Library
-    Exposed-Modules:    Data.Multimap
+    Exposed-Modules:    Data.MultiMap
+                        , Data.SetMap
     Build-Depends:      base >= 3 && < 5, containers
     Hs-Source-Dirs:     src
 
diff --git a/src/Data/MultiMap.hs b/src/Data/MultiMap.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/MultiMap.hs
@@ -0,0 +1,281 @@
+{-# LANGUAGE Haskell2010
+    , DeriveDataTypeable
+ #-}
+{-# OPTIONS
+    -Wall
+    -fno-warn-name-shadowing
+ #-}
+
+-- | A very simple MultiMap, based on 'Data.Map.Map' from the containers package.
+module Data.MultiMap (
+
+    -- * MultiMap type
+    MultiMap,
+
+    -- * Query
+    null,
+    size,
+    numKeys,
+    numValues,
+
+    member,
+    notMember,
+    lookup,
+
+    -- * Operators
+    (!),
+
+    -- * Construction
+    empty,
+    
+    -- ** Insertion
+    insert,
+
+    -- ** Delete
+    delete,
+
+    -- * Traversal
+    map,
+    mapKeys,
+    mapWithKey,
+    
+    -- * Folds
+    foldr,
+    foldl,
+    foldrWithKey,
+    foldlWithKey,
+
+    -- * Conversion
+    elems,
+    keys,
+    keysSet,
+    assocs,
+
+    toMap,
+    toMapOfSets,
+    toList,
+    fromList,
+    fromMap,
+    
+    -- * Min/Max
+    findMin,
+    findMax,
+    findMinWithValues,
+    findMaxWithValues
+
+  ) where
+
+import Prelude hiding (lookup, map, null, foldr, foldl)
+import qualified Prelude as P
+
+import qualified Data.Set as Set
+import Data.Set (Set)
+
+import qualified Data.Map as Map
+import Data.Map (Map)
+
+import Data.Word
+import Data.Data
+
+
+-- | A MultiMap with keys @k@ and values @v@.
+--
+-- A key can have multiple values (but not zero).
+-- The same value can be added multiple times (thus no
+-- constraints are ever imposed on @v@).
+--
+-- Internally this is simply a @Map k [v]@.
+-- See 'toMap' for accessing the underlying 'Map'.
+newtype MultiMap k v = MultiMap (Word32, Word32, Map k [v])
+    deriving (Data, Typeable)
+
+
+null :: MultiMap k a -> Bool
+-- ^ /O(1)./ Check whether the multimap is empty or not.
+null (MultiMap (_, _, m)) = Map.null m
+
+
+size :: MultiMap k a -> Int
+-- ^ /O(1)./ The number of elements in the multimap.
+size (MultiMap (_, size, _)) = fromIntegral size
+
+
+numKeys :: MultiMap k a -> Word32
+-- ^ /O(1)./ The number of keys in the multimap.
+-- 
+-- As this is a multimap, the number of keys is not
+-- necessarily equal to the number of values.
+numKeys (MultiMap (nk, _, _)) = nk
+
+
+numValues :: MultiMap k a -> Word32
+-- ^ /O(1)./ The number of values in the multimap.
+--
+-- As this is a multimap, the number of keys is not
+-- necessarily equal to the number of values.
+numValues (MultiMap (_, nv, _)) = nv
+
+
+notMember, member :: Ord k => MultiMap k a -> k -> Bool
+-- | /O(log n)./ Is the key a member of the multimap?
+member (MultiMap (_, _, map)) key = Map.member key map
+-- | /O(log n)./ Is the key not a member of the multimap?
+notMember key = not . member key
+
+
+(!) :: Ord k => MultiMap k a -> k -> [a]
+-- ^ As @flip lookup@
+(!) = flip lookup
+
+
+lookup :: Ord k => k -> MultiMap k a -> [a]
+-- ^ /O(log n)./ Lookup the value at a key in the map.
+--
+-- The function will return the corrsponding values as a List, or the
+-- empty list if no values are associated witht the given key.
+lookup key (MultiMap (_, _, map)) = maybe [] id (Map.lookup key map)
+
+
+empty :: MultiMap k a
+-- ^ /O(1)./ The empty multimap.
+empty = MultiMap (0, 0, Map.empty)
+
+
+insert :: Ord k => k -> a -> MultiMap k a -> MultiMap k a
+-- ^ /O(log n)./ Insert a new key and value in the map.
+insert k v (MultiMap (nk, nv, map))
+    | Map.member k map = MultiMap (nk, succ nv, Map.insert k (v : map Map.! k) map)
+    | otherwise = MultiMap (succ nk, succ nv, Map.insert k [v] map)
+
+delete :: Ord k => k -> MultiMap k a -> MultiMap k a
+-- ^ /O(log n)./ Delete a key and all its values from the map.
+delete k m@(MultiMap (nk, nv, map)) = case Map.lookup k map of
+    Just v -> MultiMap (pred nk, nv - fromIntegral (length v), Map.delete k map)
+    _      -> m
+
+
+map :: (a -> b) -> MultiMap k a -> MultiMap k b
+-- ^ Map a function over all values in the map.
+map f (MultiMap (nk, nv, map)) = MultiMap (nk, nv, Map.map (P.map f) map)
+
+
+mapKeys :: Ord k2 => (k1 -> k2) -> MultiMap k1 a -> MultiMap k2 a
+-- ^ mapKeys f s is the multimap obtained by applying f to each key of s.
+mapKeys f (MultiMap (nk, nv, map)) = MultiMap (nk, nv, Map.mapKeys f map)
+
+
+mapWithKey :: (k -> a -> b) -> MultiMap k a -> MultiMap k b
+-- ^ Map a function over all key/value pairs in the map.
+mapWithKey f (MultiMap (nk, nv, map))
+  = MultiMap (nk, nv, Map.mapWithKey (\k -> P.map (f k)) map)
+
+
+foldr :: (a -> b -> b) -> b -> MultiMap k a -> b
+-- ^ Fold the values in the map using the given right-associative binary operator.
+foldr f e = P.foldr f e . concat . elems
+
+
+foldl :: (a -> b -> a) -> a -> MultiMap k b -> a
+-- ^  Fold the values in the map using the given left-associative binary operator.
+foldl f e = P.foldl f e . concat . elems
+
+
+foldrWithKey :: (k -> a -> b -> b) -> b -> MultiMap k a -> b
+-- ^ /O(n)./ Fold the keys and values in the map using the given right-associative
+-- binary operator, taking into account not only the value but also the key.
+foldrWithKey f e = P.foldr (uncurry f) e . toList
+
+
+foldlWithKey :: (a -> k -> b -> a) -> a -> MultiMap k b -> a
+-- ^ /O(n)./ Fold the keys and values in the map using the given left-associative
+-- binary operator, taking into account not only the value but also the key.
+foldlWithKey f e = P.foldl (\a (k,v) -> f a k v) e . toList
+
+
+elems :: MultiMap k a -> [[a]]
+-- ^ /O(n)./ Return all elements of the multimap in the
+-- ascending order of their keys.
+--
+-- A list of lists is returned since a key can have
+-- multiple values. Use 'concat' to flatten.
+elems (MultiMap (_, _, map)) = Map.elems map
+
+
+keys :: MultiMap k a -> [k]
+-- ^ /O(n)./ Return all keys of the multimap in ascending order.
+keys (MultiMap (_, _, map)) = Map.keys map
+
+
+keysSet :: MultiMap k a -> Set k
+-- ^ /O(n)./ The set of all keys of the multimap.
+keysSet (MultiMap (_, _, map)) = Map.keysSet map
+
+
+assocs :: MultiMap k a -> [(k, [a])]
+-- ^ /O(n)./ Return all key/value pairs in the multimap
+-- in ascending key order.
+assocs (MultiMap (_, _, map)) = Map.assocs map
+
+
+toMap :: MultiMap k a -> Map k [a]
+-- ^ /O(1)./ Return the map of lists.
+toMap (MultiMap (_, _, theUnderlyingMap)) = theUnderlyingMap
+
+
+toMapOfSets :: Ord a => MultiMap k a -> Map k (Set a)
+-- ^ /O(k*m*log m) where k is the number of keys and m the
+-- maximum number of elements associated with a single key/
+toMapOfSets (MultiMap (_, _, map)) = Map.map Set.fromList map
+
+
+toList :: MultiMap k a -> [(k, a)]
+-- ^ Return a flattened list of key/value pairs.
+toList (MultiMap (_, _, map))
+  = concat $ Map.elems $ Map.mapWithKey (\k -> zip (repeat k)) map
+
+
+fromList :: Ord k => [(k, a)] -> MultiMap k a
+-- ^ /O(n*log n)/ Create a multimap from a list of key/value pairs.
+--
+-- > fromList xs == foldr (uncurry insert) empty
+fromList = P.foldr (uncurry insert) empty
+
+
+fromMap :: Map k [a] -> MultiMap k a
+-- ^ Turns a map of lists into a multimap.
+fromMap map = MultiMap (numKeys, numValues, map)
+  where
+    numKeys   = fromIntegral $ Map.size map
+    numValues = fromIntegral $ Map.foldr (\v s -> length v + s) 0 map
+
+
+findMin :: MultiMap k a -> Maybe k
+-- ^ /O(log n)/ Find the minimal key of the multimap.
+findMin (MultiMap (_, _, map))
+    | Map.null map = Nothing
+    | otherwise    = Just $ fst $ Map.findMin map
+
+
+findMax :: MultiMap k a -> Maybe k
+-- ^ /O(log n)/ Find the maximal key of the multimap.
+findMax (MultiMap (_, _, map))
+    | Map.null map = Nothing
+    | otherwise    = Just $ fst $ Map.findMax map
+
+
+findMinWithValues :: MultiMap k a -> Maybe (k, [a])
+-- ^ /O(log n)/ Find the minimal key and the values associated with it.
+findMinWithValues (MultiMap (_, _, map))
+    | Map.null map = Nothing
+    | otherwise    = Just $ Map.findMin map
+
+
+findMaxWithValues :: MultiMap k a -> Maybe (k, [a])
+-- ^ /O(log n)/ Find the maximal key and the values associated with it.
+findMaxWithValues (MultiMap (_, _, map))
+    | Map.null map = Nothing
+    | otherwise    = Just $ Map.findMax map
+
+
+
+
diff --git a/src/Data/Multimap.hs b/src/Data/Multimap.hs
deleted file mode 100644
--- a/src/Data/Multimap.hs
+++ /dev/null
@@ -1,272 +0,0 @@
-{-# LANGUAGE Haskell2010 #-}
-
--- | A very simple Multimap, based on 'Data.Map.Map' from the containers package.
-module Data.Multimap (
-
-    -- * Multimap type
-    Multimap,
-
-    -- * Query
-    null,
-    size,
-    numKeys,
-    numValues,
-
-    member,
-    notMember,
-    lookup,
-
-    -- * Operators
-    (!),
-
-    -- * Construction
-    empty,
-    
-    -- ** Insertion
-    insert,
-
-    -- ** Delete
-    delete,
-
-    -- * Traversal
-    map,
-    mapKeys,
-    mapWithKey,
-    
-    -- * Folds
-    foldr,
-    foldl,
-    foldrWithKey,
-    foldlWithKey,
-
-    -- * Conversion
-    elems,
-    keys,
-    keysSet,
-    assocs,
-
-    toMap,
-    toMapOfSets,
-    toList,
-    fromList,
-    fromMap,
-    
-    -- * Min/Max
-    findMin,
-    findMax,
-    findMinWithValues,
-    findMaxWithValues
-
-  ) where
-
-import Prelude hiding (lookup, map, null, foldr, foldl)
-import qualified Prelude as P
-
-import qualified Data.Set as Set
-import Data.Set (Set)
-
-import qualified Data.Map as Map
-import Data.Map (Map)
-
-import Data.Word
-
--- | A Multimap with keys @k@ and values @v@.
---
--- A key can have multiple values (but not zero).
--- The same value can be added multiple times (thus no
--- constraints are ever imposed on @v@).
---
--- Internally this is simply a @Map k [v]@.
--- See 'toMap' for accessing the underlying 'Map'.
-newtype Multimap k v = Multimap (Word32, Word32, Map k [v])
-
-
-null :: Multimap k a -> Bool
--- ^ /O(1)./ Check whether the multimap is empty or not.
-null (Multimap (_, _, m)) = Map.null m
-
-
-size :: Multimap k a -> Int
--- ^ /O(1)./ The number of elements in the multimap.
-size (Multimap (_, size, _)) = fromIntegral size
-
-
-numKeys :: Multimap k a -> Word32
--- ^ /O(1)./ The number of keys in the multimap.
--- 
--- As this is a multimap, the number of keys is not
--- necessarily equal to the number of values.
-numKeys (Multimap (nk, _, _)) = nk
-
-
-numValues :: Multimap k a -> Word32
--- ^ /O(1)./ The number of values in the multimap.
---
--- As this is a multimap, the number of keys is not
--- necessarily equal to the number of values.
-numValues (Multimap (_, nv, _)) = nv
-
-
-notMember, member :: Ord k => Multimap k a -> k -> Bool
--- | /O(log n)./ Is the key a member of the multimap?
-member (Multimap (_, _, map)) key = Map.member key map
--- | /O(log n)./ Is the key not a member of the multimap?
-notMember key = not . member key
-
-
-(!) :: Ord k => Multimap k a -> k -> [a]
--- ^ As @flip lookup@
-(!) = flip lookup
-
-
-lookup :: Ord k => k -> Multimap k a -> [a]
--- ^ /O(log n)./ Lookup the value at a key in the map.
---
--- The function will return the corrsponding values as a List, or the
--- empty list if no values are associated witht the given key.
-lookup key (Multimap (_, _, map)) = maybe [] id (Map.lookup key map)
-
-
-empty :: Multimap k a
--- ^ /O(1)./ The empty multimap.
-empty = Multimap (0, 0, Map.empty)
-
-
-insert :: Ord k => k -> a -> Multimap k a -> Multimap k a
--- ^ /O(log n)./ Insert a new key and value in the map.
-insert k v (Multimap (nk, nv, map))
-    | Map.member k map = Multimap (nk, succ nv, Map.insert k (v : map Map.! k) map)
-    | otherwise = Multimap (succ nk, succ nv, Map.insert k [v] map)
-
-delete :: Ord k => k -> a -> Multimap k a -> Multimap k a
--- ^ /O(log n)./ Delete a key and all its values from the map.
-delete k v m@(Multimap (nk, nv, map)) = case Map.lookup k map of
-    Just v -> Multimap (pred nk, nv - fromIntegral (length v), Map.delete k map)
-    _      -> m
-
-
-map :: (a -> b) -> Multimap k a -> Multimap k b
--- ^ Map a function over all values in the map.
-map f (Multimap (nk, nv, map)) = Multimap (nk, nv, Map.map (P.map f) map)
-
-
-mapKeys :: Ord k2 => (k1 -> k2) -> Multimap k1 a -> Multimap k2 a
--- ^ mapKeys f s is the multimap obtained by applying f to each key of s.
-mapKeys f (Multimap (nk, nv, map)) = Multimap (nk, nv, Map.mapKeys f map)
-
-
-mapWithKey :: (k -> a -> b) -> Multimap k a -> Multimap k b
--- ^ Map a function over all key/value pairs in the map.
-mapWithKey f (Multimap (nk, nv, map))
-  = Multimap (nk, nv, Map.mapWithKey (\k -> P.map (f k)) map)
-
-
-foldr :: (a -> b -> b) -> b -> Multimap k a -> b
--- ^ Fold the values in the map using the given right-associative binary operator.
-foldr f e = P.foldr f e . concat . elems
-
-
-foldl :: (a -> b -> a) -> a -> Multimap k b -> a
--- ^  Fold the values in the map using the given left-associative binary operator.
-foldl f e = P.foldl f e . concat . elems
-
-
-foldrWithKey :: (k -> a -> b -> b) -> b -> Multimap k a -> b
--- ^ /O(n)./ Fold the keys and values in the map using the given right-associative
--- binary operator, taking into account not only the value but also the key.
-foldrWithKey f e = P.foldr (uncurry f) e . toList
-
-
-foldlWithKey :: (a -> k -> b -> a) -> a -> Multimap k b -> a
--- ^ /O(n)./ Fold the keys and values in the map using the given left-associative
--- binary operator, taking into account not only the value but also the key.
-foldlWithKey f e = P.foldl (\a (k,v) -> f a k v) e . toList
-
-
-elems :: Multimap k a -> [[a]]
--- ^ /O(n)./ Return all elements of the multimap in the
--- ascending order of their keys.
---
--- A list of lists is returned since a key can have
--- multiple values. Use 'concat' to flatten.
-elems (Multimap (_, _, map)) = Map.elems map
-
-
-keys :: Multimap k a -> [k]
--- ^ /O(n)./ Return all keys of the multimap in ascending order.
-keys (Multimap (_, _, map)) = Map.keys map
-
-
-keysSet :: Multimap k a -> Set k
--- ^ /O(n)./ The set of all keys of the multimap.
-keysSet (Multimap (_, _, map)) = Map.keysSet map
-
-
-assocs :: Multimap k a -> [(k, [a])]
--- ^ /O(n)./ Return all key/value pairs in the multimap
--- in ascending key order.
-assocs (Multimap (_, _, map)) = Map.assocs map
-
-
-toMap :: Multimap k a -> Map k [a]
--- ^ /O(1)./ Return the map of lists.
-toMap (Multimap (_, _, theUnderlyingMap)) = theUnderlyingMap
-
-
-toMapOfSets :: Ord a => Multimap k a -> Map k (Set a)
--- ^ /O(k*m*log m) where k is the number of keys and m the
--- maximum number of elements associated with a single key/
-toMapOfSets (Multimap (_, _, map)) = Map.map Set.fromList map
-
-
-toList :: Multimap k a -> [(k, a)]
--- ^ Return a flattened list of key/value pairs.
-toList (Multimap (_, _, map))
-  = concat $ Map.elems $ Map.mapWithKey (\k -> zip (repeat k)) map
-
-
-fromList :: Ord k => [(k, a)] -> Multimap k a
--- ^ /O(n*log n)/ Create a multimap from a list of key/value pairs.
---
--- > fromList xs == foldr (uncurry insert) empty
-fromList = P.foldr (uncurry insert) empty
-
-
-fromMap :: Map k [a] -> Multimap k a
--- ^ Turns a map of lists into a multimap.
-fromMap map = Multimap (numKeys, numValues, map)
-  where
-    numKeys   = fromIntegral $ Map.size map
-    numValues = fromIntegral $ Map.foldr (\v s -> length v + s) 0 map
-
-
-findMin :: Multimap k a -> Maybe k
--- ^ /O(log n)/ Find the minimal key of the multimap.
-findMin (Multimap (_, _, map))
-    | Map.null map = Nothing
-    | otherwise    = Just $ fst $ Map.findMin map
-
-
-findMax :: Multimap k a -> Maybe k
--- ^ /O(log n)/ Find the maximal key of the multimap.
-findMax (Multimap (_, _, map))
-    | Map.null map = Nothing
-    | otherwise    = Just $ fst $ Map.findMax map
-
-
-findMinWithValues :: Multimap k a -> Maybe (k, [a])
--- ^ /O(log n)/ Find the minimal key and the values associated with it.
-findMinWithValues (Multimap (_, _, map))
-    | Map.null map = Nothing
-    | otherwise    = Just $ Map.findMin map
-
-
-findMaxWithValues :: Multimap k a -> Maybe (k, [a])
--- ^ /O(log n)/ Find the maximal key and the values associated with it.
-findMaxWithValues (Multimap (_, _, map))
-    | Map.null map = Nothing
-    | otherwise    = Just $ Map.findMax map
-
-
-
-
diff --git a/src/Data/SetMap.hs b/src/Data/SetMap.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/SetMap.hs
@@ -0,0 +1,160 @@
+{-# LANGUAGE Haskell2010
+    , DeriveDataTypeable
+ #-}
+{-# OPTIONS
+    -Wall
+    -fno-warn-name-shadowing
+ #-}
+
+-- | A SetMap allows the association of multiple values with a single key,
+-- but there are no duplicates per key.
+module Data.SetMap (
+
+    -- * SetMap type
+    SetMap,
+
+    -- * Query
+    null,
+    size,
+    numKeys,
+    numValues,
+
+    member,
+    notMember,
+    lookup,
+
+    -- * Operators
+    (!),
+
+    -- * Construction
+    empty,
+    
+    -- ** Insertion
+    insert,
+
+    -- ** Deletion
+    delete,
+
+    -- * Traversal
+    map,
+
+    -- * Conversion
+    elems,
+    keys,
+
+    toMap,
+
+  ) where
+
+
+import Prelude hiding (lookup, map, null, foldr, foldl)
+import qualified Prelude as P
+
+import qualified Data.Set as Set
+import Data.Set (Set)
+
+import qualified Data.Map as Map
+import Data.Map (Map)
+
+import Data.Word
+import Data.Data
+
+
+-- | A SetMap with keys @k@ and values @v@.
+newtype SetMap k v = SetMap (Word32, Word32, Map k (Set v))
+    deriving (Data, Typeable)
+
+
+null :: SetMap k a -> Bool
+-- ^ /O(1)./ Check whether the multimap is empty or not.
+null (SetMap (_, _, m)) = Map.null m
+
+
+size :: SetMap k a -> Int
+-- ^ /O(1)./ The number of elements in the multimap.
+size (SetMap (_, size, _)) = fromIntegral size
+
+
+numKeys :: SetMap k a -> Word32
+-- ^ /O(1)./ The number of keys in the multimap.
+-- 
+-- As this is a multimap, the number of keys is not
+-- necessarily equal to the number of values.
+numKeys (SetMap (nk, _, _)) = nk
+
+
+numValues :: SetMap k a -> Word32
+-- ^ /O(1)./ The number of values in the multimap.
+--
+-- As this is a multimap, the number of keys is not
+-- necessarily equal to the number of values.
+numValues (SetMap (_, nv, _)) = nv
+
+
+notMember, member :: Ord k => SetMap k a -> k -> Bool
+-- | /O(log n)./ Is the key a member of the multimap?
+member (SetMap (_, _, map)) key = Map.member key map
+-- | /O(log n)./ Is the key not a member of the multimap?
+notMember key = not . member key
+
+
+(!) :: Ord k => SetMap k a -> k -> Set a
+-- ^ As @flip lookup@
+(!) = flip lookup
+
+
+lookup :: Ord k => k -> SetMap k a -> Set a
+-- ^ /O(log n)./ Lookup the value at a key in the map.
+--
+-- The function will return the corrsponding values as a List, or the
+-- empty list if no values are associated witht the given key.
+lookup key (SetMap (_, _, map)) = maybe Set.empty id (Map.lookup key map)
+
+
+empty :: SetMap k a
+-- ^ /O(1)./ The empty multimap.
+empty = SetMap (0, 0, Map.empty)
+
+
+insert :: (Ord k, Ord a) => k -> a -> SetMap k a -> SetMap k a
+-- ^ Insert a new key and value in the map.
+insert k v (SetMap (nk, nv, map))
+    | Map.member k map =
+        let oldSet = map Map.! k
+            (nv', newSet) = if v `Set.member` oldSet
+                then (nv, oldSet) else (succ nv, v `Set.insert` oldSet)
+        in  SetMap (nk, nv', Map.insert k newSet map)
+    | otherwise = SetMap (succ nk, succ nv, Map.insert k (Set.singleton v) map)
+
+
+delete :: Ord k => k -> SetMap k a -> SetMap k a
+-- ^ Delete a key and all its values from the map.
+delete k m@(SetMap (nk, nv, map)) = case Map.lookup k map of
+    Just v -> SetMap (pred nk, nv - fromIntegral (Set.size v), Map.delete k map)
+    _      -> m
+
+
+map :: (Ord a, Ord b) => (a -> b) -> SetMap k a -> SetMap k b
+-- ^ Map a function over all values in the map.
+map f (SetMap (nk, nv, map)) = SetMap (nk, nv, Map.map (Set.map f) map)
+
+
+elems :: SetMap k a -> [[a]]
+-- ^ Return all elements of the multimap in the
+-- ascending order of their keys.
+--
+-- A list of lists is returned since a key can have
+-- multiple values. Use 'concat' to flatten.
+elems (SetMap (_, _, map)) = P.map (Set.elems) $ Map.elems map
+
+
+keys :: SetMap k a -> [k]
+-- ^ /O(n)./ Return all keys of the multimap in ascending order.
+keys (SetMap (_, _, map)) = Map.keys map
+
+
+toMap :: SetMap k a -> Map k (Set a)
+-- ^ /O(1)./ Return the map of sets.
+toMap (SetMap (_, _, theUnderlyingMap)) = theUnderlyingMap
+
+
