module Data.Collections
(
Unfoldable(..),
Collection(..),
Map(..),
lookupWithDefault,
unionsWith,
intersectionWith',
differenceWith',
mapWithKey',
(!),
Set(..),
unions,
notMember,
(\\),
Sequence(..),
head,
tail,
append,
concat,
concatMap,
(<|),
(|>),
(><),
Array(..),
Indexed(..),
fromFoldable,
fromAscFoldable,
fromList,
fromListWith,
fromAscList,
KeysView(..), ElemsView(..),
withKeys, withElems,
module Data.Collections.Foldable,
Seq.Seq,
IntMap.IntMap, IntSet.IntSet,
StdSet, StdMap, AvlSet, AvlMap, RangedSet
) where
import Prelude hiding (sum,concat,lookup,map,filter,foldr,foldr1,foldl,null,reverse,(++),minimum,maximum,all,elem,concatMap,drop,head,tail,init)
import Control.Monad
import Data.Monoid
import Data.Collections.Foldable
import Data.Sequence (ViewL(..), ViewR(..))
import qualified Data.Sequence as Seq
import qualified Data.Foldable as AltFoldable
import qualified Data.Array as Array
import qualified Data.IntMap as IntMap
import qualified Data.IntSet as IntSet
import qualified Data.List as List
import qualified Data.Map as Map
import qualified Data.Maybe as Maybe
import qualified Data.Set as Set
import qualified Data.Set.AVL as AvlSet
import qualified Data.Map.AVL as AvlMap
import qualified Data.Set.Enum as EnumSet
import qualified Data.ByteString as BS
import qualified Data.Ranged as Ranged
import Data.Ranged (DiscreteOrdered)
import qualified Data.ByteString.Lazy as BSL
import Data.Word (Word8)
type StdSet = Set.Set
type StdMap = Map.Map
type AvlSet = AvlSet.Set
type AvlMap = AvlMap.Map
type RangedSet = Ranged.RSet
infixl 9 !
infixl 9 \\
infixr 5 ><
infixr 5 <|
infixl 5 |>
class (Foldable c a, Unfoldable c a) => Collection c a | c -> a where
filter :: (a -> Bool) -> c -> c
class Unfoldable c i | c -> i where
insert :: i -> c -> c
empty :: c
empty = unfold (const Nothing) undefined
singleton :: i -> c
singleton i = insert i empty
insertMany :: Foldable c' i => c' -> c -> c
insertMany c' c = foldr insert c c'
insertManySorted :: Foldable c' i => c' -> c -> c
insertManySorted = insertMany
unfold :: Unfoldable c a => (b -> Maybe (a, b)) -> b -> c
unfold f b = insertMany (List.unfoldr f b) empty
class Collection c o => SortingCollection c o where
minView :: Monad m => c -> m (o,c)
fromFoldable :: (Foldable f a, Collection c' a) => f -> c'
fromFoldable = flip insertMany empty
fromAscFoldable :: (Foldable f a, Collection c' a) => f -> c'
fromAscFoldable = flip insertManySorted empty
fromList :: Collection c a => [a] -> c
fromList = fromFoldable
fromAscList :: Collection c a => [a] -> c
fromAscList = fromAscFoldable
class (Monoid c, Collection c a) => Sequence c a where
take :: Int -> c -> c
drop :: Int -> c -> c
splitAt :: Int -> c -> (c,c)
reverse :: c -> c
front :: Monad m => c -> m (a,c)
back :: Monad m => c -> m (c,a)
cons :: a -> c -> c
snoc :: c -> a -> c
isPrefix :: Eq a => c -> c -> Bool
cons = insert
isPrefix s1 s2
= case front s1 of
Nothing -> True
Just (x,xs) ->
case front s2 of
Nothing -> False
Just (y,ys) -> x == y && isPrefix xs ys
append :: Sequence c a => c -> c -> c
append = mappend
(<|) :: Sequence c i => i -> c -> c
(<|) = cons
(|>) :: Sequence c i => c -> i -> c
(|>) = snoc
(><) :: Sequence c a => c -> c -> c
(><) = append
concat :: (Sequence s a, Foldable t s) => t -> s
concat = fold
concatMap :: (Sequence s b, Foldable t a) => (a -> s) -> t -> s
concatMap = foldMap
head :: Sequence s a => s -> a
head = fst . Maybe.fromJust . front
tail :: Sequence s a => s -> s
tail = drop 1
class Indexed c k v | c -> k v where
index :: k -> c -> v
adjust :: (v -> v) -> k -> c -> c
inDomain :: k -> c -> Bool
(//) :: Foldable l (k,v) => c -> l -> c
(//) = foldr replace
where replace (k,v) = adjust (const v) k
accum :: Foldable l (k,v') => (v -> v' -> v) -> c -> l -> c
accum f = foldr adjust'
where adjust' (k,v') = adjust (\v->f v v') k
(!) :: Indexed c k v => c -> k -> v
(!) = flip index
class (Array.Ix k, Foldable c (k,v), Indexed c k v) => Array c k v | c -> k v where
bounds :: c -> (k,k)
array :: Foldable l (k,v) => (k,k) -> l -> c
class Monoid c => Map c k a | c -> k a where
delete :: k -> c -> c
delete = alter (const Nothing)
member :: k -> c -> Bool
member k = Maybe.isJust . lookup k
union :: c -> c -> c
union = unionWith const
intersection :: c -> c -> c
intersection = intersectionWith const
difference :: c -> c -> c
difference = differenceWith (\_ _-> Nothing)
isSubset :: c -> c -> Bool
isSubset = isSubmapBy (\_ _->True)
lookup :: Monad m => k -> c -> m a
alter :: (Maybe a -> Maybe a) -> k -> c -> c
alter f k m = case f (lookup k m) of
Just a -> insertWith (\x _->x) k a m
Nothing -> delete k m
insertWith :: (a -> a -> a) -> k -> a -> c -> c
insertWith f k a c = alter (\x -> Just $ case x of {Nothing->a;Just a' -> f a a'}) k c
fromFoldableWith :: Foldable l (k,a) => (a -> a -> a) -> l -> c
fromFoldableWith f = foldr (uncurry (insertWith f)) mempty
foldGroups :: Foldable l (k,b) => (b -> a -> a) -> a -> l -> c
foldGroups f a = foldr' (\(k,b) c -> (alter (\x -> Just $ case x of {Nothing->f b a;Just a' -> f b a'}) k c)) mempty
mapWithKey :: (k -> a -> a) -> c -> c
unionWith :: (a -> a -> a) -> c -> c -> c
intersectionWith :: (a -> a -> a) -> c -> c -> c
differenceWith :: (a -> a -> Maybe a) -> c -> c -> c
isSubmapBy :: (a -> a -> Bool) -> c -> c -> Bool
notMember :: (Map c k a) => k -> c -> Bool
notMember k s = not $ member k s
lookupWithDefault :: (Map c k a) => a -> k -> c -> a
lookupWithDefault a k c = Maybe.fromMaybe a (lookup k c)
fromListWith :: (Map c k a) => (a -> a -> a) -> [(k,a)] -> c
fromListWith = fromFoldableWith
data O a b c = L !a | R !b | O !c
intersectionWith' :: (Functor m, Map (m (O a b c)) k (O a b c)) =>
(a->b->c) -> m a -> m b -> m c
intersectionWith' f m1 m2 = fmap extract (intersectionWith combine (fmap L m1) (fmap R m2))
where combine (L l) (R r) = O (f l r)
extract (O a) = a
differenceWith' :: (Functor m, Map (m (O a b c)) k (O a b c)) =>
(a->b->Maybe c) -> m a -> m b -> m c
differenceWith' f m1 m2 = fmap extract (differenceWith combine (fmap L m1) (fmap R m2))
where combine (L l) (R r) = fmap O (f l r)
extract (O a) = a
mapWithKey' :: (Functor m, Map (m (Either a b)) k (Either a b)) =>
(k -> a -> b) -> m a -> m b
mapWithKey' f = fmap (either (error "mapWithKey': bug.") id) . mapWithKey f' . fmap Left
where f' k (Left x) = Right (f k x)
class Map c k () => Set c k | c -> k where
haddock_candy :: c -> k
(\\) :: Map c k a => c -> c -> c
(\\) = difference
(\/) :: Map c k a => c -> c -> c
(\/) = union
(/\) :: Map c k a => c -> c -> c
(/\) = intersection
unions :: (Unfoldable s i, Map s k a, Foldable cs s) => cs -> s
unions sets = foldl' union empty sets
unionsWith :: (Unfoldable s i, Map s k a, Foldable cs s) => (a->a->a) -> cs -> s
unionsWith f sets = foldl' (unionWith f) empty sets
instance Unfoldable [a] a where
empty = []
singleton = return
insert = (:)
instance Collection [a] a where
filter = List.filter
instance Sequence [a] a where
take = List.take
drop = List.drop
splitAt = List.splitAt
reverse = List.reverse
front (x:xs) = return (x,xs)
front [] = fail "front: empty sequence"
back s = return swap `ap` front (reverse s)
where swap (x,s) = (reverse s,x)
cons = (:)
snoc xs x = xs List.++ [x]
isPrefix = List.isPrefixOf
instance Indexed [a] Int a where
index = flip (List.!!)
adjust f k l = left >< (f x:right)
where (left,x:right) = List.splitAt k l
inDomain k l = k >= 0 && k < List.length l
instance Unfoldable (Seq.Seq a) a where
empty = Seq.empty
singleton = return
insert = (<|)
instance Foldable (Seq.Seq a) a where
foldr = AltFoldable.foldr
foldl = AltFoldable.foldl
foldr1 = AltFoldable.foldr1
foldl1 = AltFoldable.foldl1
foldMap = AltFoldable.foldMap
null = Seq.null
instance Collection (Seq.Seq a) a where
filter f = fromList . filter f . fromFoldable
instance Sequence (Seq.Seq a) a where
take = Seq.take
drop = Seq.drop
splitAt = Seq.splitAt
reverse = Seq.reverse
front s = case Seq.viewl s of
EmptyL -> fail "front: empty sequence"
a :< s -> return (a,s)
back s = case Seq.viewr s of
EmptyR -> fail "back: empty sequence"
s :> a -> return (s,a)
cons = (Seq.<|)
snoc = (Seq.|>)
instance Indexed (Seq.Seq a) Int a where
index = flip Seq.index
adjust = Seq.adjust
inDomain k l = k >= 0 && k < Seq.length l
instance Foldable BS.ByteString Word8 where
fold = foldr (+) 0
foldr = BS.foldr
foldl = BS.foldl
foldr1 = BS.foldr1
foldl1 = BS.foldl1
null = BS.null
size = BS.length
instance Unfoldable BS.ByteString Word8 where
empty = BS.empty
singleton = BS.singleton
insert = BS.cons
instance Collection BS.ByteString Word8 where
filter = BS.filter
instance Sequence BS.ByteString Word8 where
take = BS.take
drop = BS.drop
splitAt = BS.splitAt
reverse = BS.reverse
front s = if BS.null s then fail "front: empty ByteString" else return (BS.head s,BS.tail s)
back s = if BS.null s
then fail "back: empty sequence"
else let (s',x) = BS.splitAt (BS.length s 1) s in return (s', BS.head x)
cons = BS.cons
snoc = BS.snoc
instance Indexed BS.ByteString Int Word8 where
index = flip BS.index
adjust = error "Indexed.ajust: not supported by ByteString"
inDomain k l = k >= 0 && k < BS.length l
instance Foldable BSL.ByteString Word8 where
fold = foldr (+) 0
foldr = BSL.foldr
foldl = BSL.foldl
foldr1 = BSL.foldr1
foldl1 = BSL.foldl1
null = BSL.null
size = fromIntegral . BSL.length
instance Unfoldable BSL.ByteString Word8 where
empty = BSL.empty
singleton = BSL.singleton
insert = BSL.cons
instance Collection BSL.ByteString Word8 where
filter = BSL.filter
instance Sequence BSL.ByteString Word8 where
take = BSL.take . fromIntegral
drop = BSL.drop . fromIntegral
splitAt = BSL.splitAt . fromIntegral
reverse = BSL.reverse
front s = if BSL.null s then fail "front: empty ByteString" else return (BSL.head s,BSL.tail s)
back s = if BSL.null s
then fail "back: empty sequence"
else let (s',x) = BSL.splitAt (BSL.length s 1) s in return (s', BSL.head x)
cons = BSL.cons
snoc = BSL.snoc
instance Indexed BSL.ByteString Int Word8 where
index = flip BSL.index . fromIntegral
adjust = error "Indexed.ajust: not supported by ByteString.Lazy yet"
inDomain k l = k >= 0 && k < size l
instance Array.Ix i => Indexed (Array.Array i e) i e where
index = flip (Array.!)
adjust f k a = a Array.// [(k,f (a ! k))]
inDomain k a = Array.inRange (Array.bounds a) k
(//) a l = (Array.//) a (toList l)
instance Array.Ix i => Array (Array.Array i e) i e where
array b l = Array.array b (toList l)
bounds = Array.bounds
instance Foldable (Map.Map k a) (k,a) where
foldr f i m = Map.foldWithKey (curry f) i m
null = Map.null
instance Ord k => Unfoldable (Map.Map k a) (k,a) where
insert = uncurry Map.insert
singleton (k,a) = Map.singleton k a
empty = Map.empty
instance Ord k => Collection (Map.Map k a) (k,a) where
filter f = Map.filterWithKey (curry f)
instance Ord k => Indexed (Map.Map k a) k a where
index = flip (Map.!)
adjust = Map.adjust
inDomain = member
instance Ord k => Map (Map.Map k a) k a where
isSubmapBy = Map.isSubmapOfBy
isSubset = Map.isSubmapOfBy (\_ _->True)
member = Map.member
union = Map.union
difference = Map.difference
delete = Map.delete
intersection = Map.intersection
lookup x y = lifted $ Map.lookup x y
alter = Map.alter
insertWith = Map.insertWith
unionWith = Map.unionWith
intersectionWith = Map.intersectionWith
differenceWith = Map.differenceWith
mapWithKey = Map.mapWithKey
instance Ord k => SortingCollection (Map.Map k a) (k,a) where
minView x = lifted $ Map.minViewWithKey x
where swap (x,y) = (y,x)
lifted :: Monad m => Maybe a -> m a
lifted action =
case action of Nothing -> fail "missing key (probably)" ; Just x -> return x
instance Foldable (AvlMap.Map k a) (k,a) where
foldr f i m = AvlMap.foldWithKey (curry f) i m
null = AvlMap.null
instance Ord k => Unfoldable (AvlMap.Map k a) (k,a) where
insert = uncurry AvlMap.insert
singleton (k,a) = AvlMap.singleton k a
empty = AvlMap.empty
instance Ord k => Collection (AvlMap.Map k a) (k,a) where
filter f = AvlMap.filterWithKey (curry f)
instance Ord k => Indexed (AvlMap.Map k a) k a where
index = flip (AvlMap.!)
adjust = AvlMap.adjust
inDomain = member
instance Ord k => Map (AvlMap.Map k a) k a where
isSubmapBy = AvlMap.isSubmapOfBy
isSubset = AvlMap.isSubmapOfBy (\_ _->True)
member = AvlMap.member
union = AvlMap.union
difference = AvlMap.difference
delete = AvlMap.delete
intersection = AvlMap.intersection
lookup = AvlMap.lookup
alter = AvlMap.alter
insertWith = AvlMap.insertWith
unionWith = AvlMap.unionWith
intersectionWith = AvlMap.intersectionWith
differenceWith = AvlMap.differenceWith
mapWithKey = AvlMap.mapWithKey
instance Ord k => SortingCollection (AvlMap.Map k a) (k,a) where
minView c = if null c then fail "Data.AVL.Map.minView: empty map" else return (AvlMap.findMin c, AvlMap.deleteMin c)
instance Foldable (IntMap.IntMap a) (Int,a) where
null = IntMap.null
size = IntMap.size
foldr f i m = IntMap.foldWithKey (curry f) i m
instance Unfoldable (IntMap.IntMap a) (Int,a) where
insert = uncurry IntMap.insert
singleton (k,a) = IntMap.singleton k a
empty = IntMap.empty
instance Collection (IntMap.IntMap a) (Int,a) where
filter f = IntMap.filterWithKey (curry f)
instance Indexed (IntMap.IntMap a) Int a where
index = flip (IntMap.!)
adjust = IntMap.adjust
inDomain = member
instance Map (IntMap.IntMap a) Int a where
isSubmapBy = IntMap.isSubmapOfBy
isSubset = IntMap.isSubmapOfBy (\_ _->True)
member = IntMap.member
union = IntMap.union
difference = IntMap.difference
delete = IntMap.delete
intersection = IntMap.intersection
lookup x y = lifted $ IntMap.lookup x y
alter = IntMap.alter
insertWith = IntMap.insertWith
unionWith = IntMap.unionWith
intersectionWith = IntMap.intersectionWith
differenceWith = IntMap.differenceWith
mapWithKey = IntMap.mapWithKey
instance Foldable (Set.Set a) a where
foldr f i s = Set.fold f i s
null = Set.null
size = Set.size
instance Ord a => Unfoldable (Set.Set a) a where
insert = Set.insert
singleton = Set.singleton
empty = Set.empty
instance Ord a => Collection (Set.Set a) a where
filter = Set.filter
instance Ord a => Set (Set.Set a) a where
haddock_candy = haddock_candy
instance Ord a => Map (Set.Set a) a () where
isSubset = Set.isSubsetOf
isSubmapBy f x y = isSubset x y && (f () () || null (intersection x y))
member = Set.member
union = Set.union
difference = Set.difference
intersection = Set.intersection
delete = Set.delete
insertWith _f k () = insert k
unionWith _f = union
intersectionWith _f = intersection
differenceWith f s1 s2 = if f () () == Nothing then difference s1 s2 else s1
lookup k l = if member k l then return () else fail "element not found"
alter f k m = case f (lookup k m) of
Just _ -> insert k m
Nothing -> delete k m
mapWithKey _f = id
instance Ord a => SortingCollection (Set.Set a) a where
minView c = if null c then fail "Data.Set.minView: empty set" else return (Set.findMin c, Set.deleteMin c)
instance Foldable (AvlSet.Set a) a where
foldr f i s = AvlSet.fold f i s
null = AvlSet.null
instance Ord a => Unfoldable (AvlSet.Set a) a where
insert = AvlSet.insert
singleton = AvlSet.singleton
empty = AvlSet.empty
instance Ord a => Collection (AvlSet.Set a) a where
filter = AvlSet.filter
instance Ord a => Set (AvlSet.Set a) a where
haddock_candy = haddock_candy
instance Ord a => Map (AvlSet.Set a) a () where
isSubmapBy f x y = isSubset x y && (f () () || null (intersection x y))
isSubset = AvlSet.isSubsetOf
member = AvlSet.member
union = AvlSet.union
difference = AvlSet.difference
intersection = AvlSet.intersection
delete = AvlSet.delete
insertWith _f k () = insert k
unionWith _f = union
intersectionWith _f = intersection
differenceWith f s1 s2 = if f () () == Nothing then difference s1 s2 else s1
lookup k l = if member k l then return () else fail "element not found"
alter f k m = case f (lookup k m) of
Just _ -> insert k m
Nothing -> delete k m
mapWithKey _f = id
instance Ord a => SortingCollection (AvlSet.Set a) a where
minView c = if null c then fail "Data.AVL.Set.minView: empty map" else return (AvlSet.findMin c, AvlSet.deleteMin c)
instance Foldable IntSet.IntSet Int where
foldr f i s = IntSet.fold f i s
fold = foldl (+) 0
null = IntSet.null
size = IntSet.size
instance Unfoldable IntSet.IntSet Int where
insert = IntSet.insert
singleton = IntSet.singleton
empty = IntSet.empty
instance Collection IntSet.IntSet Int where
filter = IntSet.filter
instance Set IntSet.IntSet Int where
haddock_candy = haddock_candy
instance Map IntSet.IntSet Int () where
isSubmapBy f x y = isSubset x y && (f () () || null (intersection x y))
isSubset = IntSet.isSubsetOf
member = IntSet.member
union = IntSet.union
difference = IntSet.difference
intersection = IntSet.intersection
delete = IntSet.delete
insertWith _f k () = insert k
unionWith _f = union
intersectionWith _f = intersection
differenceWith f s1 s2 = if f () () == Nothing then difference s1 s2 else s1
lookup k l = if member k l then return () else fail "element not found"
alter f k m = case f (lookup k m) of
Just _ -> insert k m
Nothing -> delete k m
mapWithKey _f = id
instance Enum a => Foldable (EnumSet.Set a) a where
foldr f i s = EnumSet.foldr f i s
null = EnumSet.null
size = EnumSet.size
instance Enum a => Unfoldable (EnumSet.Set a) a where
insert = EnumSet.insert
singleton = EnumSet.singleton
empty = EnumSet.empty
instance Enum a => Collection (EnumSet.Set a) a where
filter = EnumSet.filter
instance Enum a => Set (EnumSet.Set a) a where
haddock_candy = haddock_candy
instance Enum a => Map (EnumSet.Set a) a () where
isSubmapBy f x y = isSubset x y && (f () () || null (intersection x y))
isSubset = EnumSet.isSubsetOf
member = EnumSet.member
union = EnumSet.union
difference = EnumSet.difference
intersection = EnumSet.intersection
delete = EnumSet.delete
insertWith _f k () = insert k
unionWith _f = union
intersectionWith _f = intersection
differenceWith f s1 s2 = if f () () == Nothing then difference s1 s2 else s1
lookup k l = if member k l then return () else fail "element not found"
alter f k m = case f (lookup k m) of
Just _ -> insert k m
Nothing -> delete k m
mapWithKey _f = id
instance DiscreteOrdered a => Unfoldable (RangedSet a) a where
insert x = Ranged.rSetUnion (Ranged.rSingleton x)
singleton = Ranged.rSingleton
empty = Ranged.rSetEmpty
instance DiscreteOrdered a => Map (RangedSet a) a () where
isSubset = Ranged.rSetIsSubset
isSubmapBy f x y = isSubset x y && (f () () || Ranged.rSetIsEmpty (intersection x y))
member = flip Ranged.rSetHas
union = Ranged.rSetUnion
difference = Ranged.rSetDifference
intersection = Ranged.rSetIntersection
delete = flip Ranged.rSetDifference . Ranged.rSingleton
insertWith _f k () = insert k
unionWith _f = union
intersectionWith _f = intersection
differenceWith f s1 s2 = if f () () == Nothing then difference s1 s2 else s1
lookup k l = if member k l then return () else fail "element not found"
alter f k m = case f (lookup k m) of
Just _ -> insert k m
Nothing -> delete k m
mapWithKey _f = id
instance DiscreteOrdered a => Set (RangedSet a) a where
haddock_candy = haddock_candy
newtype KeysView m k v = KeysView {fromKeysView :: m}
newtype ElemsView m k v = ElemsView {fromElemsView :: m}
type T a = a->a
withKeys :: Collection m (k,v) => T (KeysView m k v) -> T m
withKeys f c = fromKeysView $ f (KeysView c)
withElems :: Collection m (k,v) => T (ElemsView m k v) -> T m
withElems f c = fromElemsView $ f (ElemsView c)
instance Foldable m (k,v) => Foldable (KeysView m k v) k where
foldr f i (KeysView c) = foldr (f . fst) i c
null (KeysView c) = null c
instance Unfoldable m (k,v) => Unfoldable (KeysView m k v) (k,v) where
empty = KeysView empty
insert x (KeysView m) = KeysView $ insert x m
singleton x = KeysView (singleton x)
instance Foldable m (k,v) => Foldable (ElemsView m k v) v where
foldr f i (ElemsView c) = foldr (f . snd) i c
null (ElemsView c) = null c
instance Unfoldable m (k,v) => Unfoldable (ElemsView m k v) (k,v) where
empty = ElemsView empty
insert x (ElemsView m) = ElemsView $ insert x m
singleton x = ElemsView (singleton x)
instance (Monoid m, Map m k v) => Monoid (KeysView m k v) where
mempty = KeysView mempty
mappend = union
instance Map m k v => Map (KeysView m k v) k v where
isSubmapBy f (KeysView m) (KeysView m') = isSubmapBy f m m'
member k (KeysView m) = Maybe.isJust $ lookup k m
union (KeysView m) (KeysView m') = KeysView $ union m m'
difference (KeysView m) (KeysView m') = KeysView $ difference m m'
intersection (KeysView m) (KeysView m') = KeysView $ intersection m m'
delete k (KeysView m) = KeysView $ delete k m
insertWith f k a (KeysView m) = KeysView $ insertWith f k a m
lookup k (KeysView m) = lookup k m
alter f k (KeysView m) = KeysView $ alter f k m
unionWith f (KeysView m) (KeysView m') = KeysView $ unionWith f m m'
differenceWith f (KeysView m) (KeysView m') = KeysView $ differenceWith f m m'
intersectionWith f (KeysView m) (KeysView m') = KeysView $ intersectionWith f m m'
mapWithKey f (KeysView m) = KeysView $ mapWithKey f m