nonempty-containers 0.3.6.0 → 0.4.0.0
raw patch · 20 files changed
+13645/−6008 lines, 20 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.Containers.NonEmpty.List: instance Data.Containers.NonEmpty.List.IsNonEmptyList (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.Containers.NonEmpty.List: instance GHC.Classes.Ord k => Data.Containers.NonEmpty.List.IsNonEmptyList (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.IntMap.NonEmpty: (!) :: NEIntMap a -> Key -> a
- Data.IntMap.NonEmpty: (!?) :: NEIntMap a -> Key -> Maybe a
- Data.IntMap.NonEmpty: (\\) :: NEIntMap a -> NEIntMap b -> IntMap a
- Data.IntMap.NonEmpty: adjust :: (a -> a) -> Key -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: adjustMax :: (a -> a) -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: adjustMaxWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: adjustMin :: (a -> a) -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: adjustMinWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: adjustWithKey :: (Key -> a -> a) -> Key -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: alter :: (Maybe a -> Maybe a) -> Key -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: alter' :: (Maybe a -> a) -> Key -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> NEIntMap a -> f (IntMap a)
- Data.IntMap.NonEmpty: alterF' :: Functor f => (Maybe a -> f a) -> Key -> NEIntMap a -> f (NEIntMap a)
- Data.IntMap.NonEmpty: assocs :: NEIntMap a -> NonEmpty (Key, a)
- Data.IntMap.NonEmpty: data NEIntMap a
- Data.IntMap.NonEmpty: delete :: Key -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: deleteFindMax :: NEIntMap a -> ((Key, a), IntMap a)
- Data.IntMap.NonEmpty: deleteFindMin :: NEIntMap a -> ((Key, a), IntMap a)
- Data.IntMap.NonEmpty: deleteMax :: NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: deleteMaybe :: Key -> NEIntMap a -> Maybe (NEIntMap a)
- Data.IntMap.NonEmpty: deleteMin :: NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: difference :: NEIntMap a -> NEIntMap b -> IntMap a
- Data.IntMap.NonEmpty: differenceWith :: (a -> b -> Maybe a) -> NEIntMap a -> NEIntMap b -> IntMap a
- Data.IntMap.NonEmpty: differenceWithKey :: (Key -> a -> b -> Maybe a) -> NEIntMap a -> NEIntMap b -> IntMap a
- Data.IntMap.NonEmpty: elems :: NEIntMap a -> NonEmpty a
- Data.IntMap.NonEmpty: filter :: (a -> Bool) -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: filterWithKey :: (Key -> a -> Bool) -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: findMax :: NEIntMap a -> (Key, a)
- Data.IntMap.NonEmpty: findMin :: NEIntMap a -> (Key, a)
- Data.IntMap.NonEmpty: findWithDefault :: a -> Key -> NEIntMap a -> a
- Data.IntMap.NonEmpty: foldMapWithKey :: Semigroup m => (Key -> a -> m) -> NEIntMap a -> m
- Data.IntMap.NonEmpty: foldl :: (a -> b -> a) -> a -> NEIntMap b -> a
- Data.IntMap.NonEmpty: foldl' :: (a -> b -> a) -> a -> NEIntMap b -> a
- Data.IntMap.NonEmpty: foldl1 :: (a -> a -> a) -> NEIntMap a -> a
- Data.IntMap.NonEmpty: foldl1' :: (a -> a -> a) -> NEIntMap a -> a
- Data.IntMap.NonEmpty: foldlWithKey :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a
- Data.IntMap.NonEmpty: foldlWithKey' :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a
- Data.IntMap.NonEmpty: foldr :: (a -> b -> b) -> b -> NEIntMap a -> b
- Data.IntMap.NonEmpty: foldr' :: (a -> b -> b) -> b -> NEIntMap a -> b
- Data.IntMap.NonEmpty: foldr1 :: (a -> a -> a) -> NEIntMap a -> a
- Data.IntMap.NonEmpty: foldr1' :: (a -> a -> a) -> NEIntMap a -> a
- Data.IntMap.NonEmpty: foldrWithKey :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b
- Data.IntMap.NonEmpty: foldrWithKey' :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b
- Data.IntMap.NonEmpty: fromAscList :: NonEmpty (Key, a) -> NEIntMap a
- Data.IntMap.NonEmpty: fromAscListWith :: (a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
- Data.IntMap.NonEmpty: fromAscListWithKey :: (Key -> a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
- Data.IntMap.NonEmpty: fromDistinctAscList :: NonEmpty (Key, a) -> NEIntMap a
- Data.IntMap.NonEmpty: fromList :: NonEmpty (Key, a) -> NEIntMap a
- Data.IntMap.NonEmpty: fromListWith :: (a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
- Data.IntMap.NonEmpty: fromListWithKey :: (Key -> a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
- Data.IntMap.NonEmpty: fromSet :: (Key -> a) -> NEIntSet -> NEIntMap a
- Data.IntMap.NonEmpty: infixl 9 !
- Data.IntMap.NonEmpty: insert :: Key -> a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> NEIntMap a -> (Maybe a, NEIntMap a)
- Data.IntMap.NonEmpty: insertMap :: Key -> a -> IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: insertMapMax :: Key -> a -> IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: insertMapMin :: Key -> a -> IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: insertMapWith :: (a -> a -> a) -> Key -> a -> IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: insertMapWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: insertWith :: (a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: intersection :: NEIntMap a -> NEIntMap b -> IntMap a
- Data.IntMap.NonEmpty: intersectionWith :: (a -> b -> c) -> NEIntMap a -> NEIntMap b -> IntMap c
- Data.IntMap.NonEmpty: intersectionWithKey :: (Key -> a -> b -> c) -> NEIntMap a -> NEIntMap b -> IntMap c
- Data.IntMap.NonEmpty: isProperSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool
- Data.IntMap.NonEmpty: isProperSubmapOfBy :: (a -> b -> Bool) -> NEIntMap a -> NEIntMap b -> Bool
- Data.IntMap.NonEmpty: isSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool
- Data.IntMap.NonEmpty: isSubmapOfBy :: (a -> b -> Bool) -> NEIntMap a -> NEIntMap b -> Bool
- Data.IntMap.NonEmpty: keys :: NEIntMap a -> NonEmpty Key
- Data.IntMap.NonEmpty: keysSet :: NEIntMap a -> NEIntSet
- Data.IntMap.NonEmpty: lookup :: Key -> NEIntMap a -> Maybe a
- Data.IntMap.NonEmpty: lookupGE :: Key -> NEIntMap a -> Maybe (Key, a)
- Data.IntMap.NonEmpty: lookupGT :: Key -> NEIntMap a -> Maybe (Key, a)
- Data.IntMap.NonEmpty: lookupLE :: Key -> NEIntMap a -> Maybe (Key, a)
- Data.IntMap.NonEmpty: lookupLT :: Key -> NEIntMap a -> Maybe (Key, a)
- Data.IntMap.NonEmpty: map :: (a -> b) -> NEIntMap a -> NEIntMap b
- Data.IntMap.NonEmpty: mapAccum :: (a -> b -> (a, c)) -> a -> NEIntMap b -> (a, NEIntMap c)
- Data.IntMap.NonEmpty: mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> NEIntMap b -> (a, NEIntMap c)
- Data.IntMap.NonEmpty: mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> NEIntMap b -> (a, NEIntMap c)
- Data.IntMap.NonEmpty: mapEither :: (a -> Either b c) -> NEIntMap a -> These (NEIntMap b) (NEIntMap c)
- Data.IntMap.NonEmpty: mapEitherWithKey :: (Key -> a -> Either b c) -> NEIntMap a -> These (NEIntMap b) (NEIntMap c)
- Data.IntMap.NonEmpty: mapKeys :: (Key -> Key) -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: mapKeysMonotonic :: (Key -> Key) -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: mapMaybe :: (a -> Maybe b) -> NEIntMap a -> IntMap b
- Data.IntMap.NonEmpty: mapMaybeWithKey :: (Key -> a -> Maybe b) -> NEIntMap a -> IntMap b
- Data.IntMap.NonEmpty: mapWithKey :: (Key -> a -> b) -> NEIntMap a -> NEIntMap b
- Data.IntMap.NonEmpty: maxView :: NEIntMap a -> (a, IntMap a)
- Data.IntMap.NonEmpty: member :: Key -> NEIntMap a -> Bool
- Data.IntMap.NonEmpty: minView :: NEIntMap a -> (a, IntMap a)
- Data.IntMap.NonEmpty: nonEmptyMap :: IntMap a -> Maybe (NEIntMap a)
- Data.IntMap.NonEmpty: notMember :: Key -> NEIntMap a -> Bool
- Data.IntMap.NonEmpty: partition :: (a -> Bool) -> NEIntMap a -> These (NEIntMap a) (NEIntMap a)
- Data.IntMap.NonEmpty: partitionWithKey :: (Key -> a -> Bool) -> NEIntMap a -> These (NEIntMap a) (NEIntMap a)
- Data.IntMap.NonEmpty: pattern IsEmpty :: IntMap a
- Data.IntMap.NonEmpty: pattern IsNonEmpty :: NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: restrictKeys :: NEIntMap a -> IntSet -> IntMap a
- Data.IntMap.NonEmpty: singleton :: Key -> a -> NEIntMap a
- Data.IntMap.NonEmpty: size :: NEIntMap a -> Int
- Data.IntMap.NonEmpty: split :: Key -> NEIntMap a -> Maybe (These (NEIntMap a) (NEIntMap a))
- Data.IntMap.NonEmpty: splitLookup :: Key -> NEIntMap a -> These a (These (NEIntMap a) (NEIntMap a))
- Data.IntMap.NonEmpty: splitRoot :: NEIntMap a -> NonEmpty (NEIntMap a)
- Data.IntMap.NonEmpty: toAscList :: NEIntMap a -> NonEmpty (Key, a)
- Data.IntMap.NonEmpty: toDescList :: NEIntMap a -> NonEmpty (Key, a)
- Data.IntMap.NonEmpty: toList :: NEIntMap a -> NonEmpty (Key, a)
- Data.IntMap.NonEmpty: toMap :: NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: traverseWithKey :: Applicative t => (Key -> a -> t b) -> NEIntMap a -> t (NEIntMap b)
- Data.IntMap.NonEmpty: traverseWithKey1 :: Apply t => (Key -> a -> t b) -> NEIntMap a -> t (NEIntMap b)
- Data.IntMap.NonEmpty: type Key = Int
- Data.IntMap.NonEmpty: union :: NEIntMap a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: unionMapLeft :: IntMap a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: unionMapRight :: NEIntMap a -> IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: unionMapWithKeyLeft :: (Key -> a -> a -> a) -> IntMap a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: unionMapWithKeyRight :: (Key -> a -> a -> a) -> NEIntMap a -> IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: unionMapWithLeft :: (a -> a -> a) -> IntMap a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: unionMapWithRight :: (a -> a -> a) -> NEIntMap a -> IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: unionWith :: (a -> a -> a) -> NEIntMap a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: unionWithKey :: (Key -> a -> a -> a) -> NEIntMap a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: unions :: Foldable1 f => f (NEIntMap a) -> NEIntMap a
- Data.IntMap.NonEmpty: unionsWith :: Foldable1 f => (a -> a -> a) -> f (NEIntMap a) -> NEIntMap a
- Data.IntMap.NonEmpty: unsafeFromMap :: IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty: update :: (a -> Maybe a) -> Key -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> NEIntMap a -> (Maybe a, IntMap a)
- Data.IntMap.NonEmpty: updateMax :: (a -> Maybe a) -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: updateMaxWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: updateMin :: (a -> Maybe a) -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: updateMinWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: updateWithKey :: (Key -> a -> Maybe a) -> Key -> NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty: valid :: NEIntMap a -> Bool
- Data.IntMap.NonEmpty: withNonEmpty :: r -> (NEIntMap a -> r) -> IntMap a -> r
- Data.IntMap.NonEmpty: withoutKeys :: NEIntMap a -> IntSet -> IntMap a
- Data.IntMap.NonEmpty.Internal: NEIntMap :: !Key -> a -> !IntMap a -> NEIntMap a
- Data.IntMap.NonEmpty.Internal: [neimIntMap] :: NEIntMap a -> !IntMap a
- Data.IntMap.NonEmpty.Internal: [neimK0] :: NEIntMap a -> !Key
- Data.IntMap.NonEmpty.Internal: [neimV0] :: NEIntMap a -> a
- Data.IntMap.NonEmpty.Internal: data NEIntMap a
- Data.IntMap.NonEmpty.Internal: elems :: NEIntMap a -> NonEmpty a
- Data.IntMap.NonEmpty.Internal: foldMapWithKey :: Semigroup m => (Key -> a -> m) -> NEIntMap a -> m
- Data.IntMap.NonEmpty.Internal: foldl :: (a -> b -> a) -> a -> NEIntMap b -> a
- Data.IntMap.NonEmpty.Internal: foldl' :: (a -> b -> a) -> a -> NEIntMap b -> a
- Data.IntMap.NonEmpty.Internal: foldl1 :: (a -> a -> a) -> NEIntMap a -> a
- Data.IntMap.NonEmpty.Internal: foldr :: (a -> b -> b) -> b -> NEIntMap a -> b
- Data.IntMap.NonEmpty.Internal: foldr' :: (a -> b -> b) -> b -> NEIntMap a -> b
- Data.IntMap.NonEmpty.Internal: foldr1 :: (a -> a -> a) -> NEIntMap a -> a
- Data.IntMap.NonEmpty.Internal: fromList :: NonEmpty (Key, a) -> NEIntMap a
- Data.IntMap.NonEmpty.Internal: insertMaxMap :: Key -> a -> IntMap a -> IntMap a
- Data.IntMap.NonEmpty.Internal: insertMinMap :: Key -> a -> IntMap a -> IntMap a
- Data.IntMap.NonEmpty.Internal: insertWith :: (a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty.Internal: instance Control.Comonad.Comonad Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.IntMap.NonEmpty.Internal: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.IntMap.NonEmpty.Internal: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.IntMap.NonEmpty.Internal: instance Data.Data.Data a => Data.Data.Data (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.IntMap.NonEmpty.Internal: instance Data.Foldable.Foldable Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Data.Foldable1.Foldable1 Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Data.Functor.Alt.Alt Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Data.Functor.Classes.Eq1 Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Data.Functor.Classes.Ord1 Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Data.Functor.Classes.Read1 Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Data.Functor.Classes.Show1 Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Data.Functor.Invariant.Invariant Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Data.Semigroup.Traversable.Class.Traversable1 Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance Data.Traversable.Traversable Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance GHC.Base.Functor Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance GHC.Base.Semigroup (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.IntMap.NonEmpty.Internal: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.IntMap.NonEmpty.Internal: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.IntMap.NonEmpty.Internal: instance GHC.IsList.IsList (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.IntMap.NonEmpty.Internal: instance GHC.Read.Read e => GHC.Read.Read (Data.IntMap.NonEmpty.Internal.NEIntMap e)
- Data.IntMap.NonEmpty.Internal: instance GHC.Show.Show a => GHC.Show.Show (Data.IntMap.NonEmpty.Internal.NEIntMap a)
- Data.IntMap.NonEmpty.Internal: instance WithIndex.FoldableWithIndex GHC.Types.Int Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance WithIndex.FunctorWithIndex GHC.Types.Int Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: instance WithIndex.TraversableWithIndex GHC.Types.Int Data.IntMap.NonEmpty.Internal.NEIntMap
- Data.IntMap.NonEmpty.Internal: map :: (a -> b) -> NEIntMap a -> NEIntMap b
- Data.IntMap.NonEmpty.Internal: nonEmptyMap :: IntMap a -> Maybe (NEIntMap a)
- Data.IntMap.NonEmpty.Internal: singleton :: Key -> a -> NEIntMap a
- Data.IntMap.NonEmpty.Internal: size :: NEIntMap a -> Int
- Data.IntMap.NonEmpty.Internal: toList :: NEIntMap a -> NonEmpty (Key, a)
- Data.IntMap.NonEmpty.Internal: toMap :: NEIntMap a -> IntMap a
- Data.IntMap.NonEmpty.Internal: traverseWithKey :: Applicative t => (Key -> a -> t b) -> NEIntMap a -> t (NEIntMap b)
- Data.IntMap.NonEmpty.Internal: traverseWithKey1 :: Apply t => (Key -> a -> t b) -> NEIntMap a -> t (NEIntMap b)
- Data.IntMap.NonEmpty.Internal: type Key = Int
- Data.IntMap.NonEmpty.Internal: union :: NEIntMap a -> NEIntMap a -> NEIntMap a
- Data.IntMap.NonEmpty.Internal: unions :: Foldable1 f => f (NEIntMap a) -> NEIntMap a
- Data.IntMap.NonEmpty.Internal: valid :: NEIntMap a -> Bool
- Data.IntMap.NonEmpty.Internal: withNonEmpty :: r -> (NEIntMap a -> r) -> IntMap a -> r
- Data.Map.NonEmpty: (!) :: Ord k => NEMap k a -> k -> a
- Data.Map.NonEmpty: (!?) :: Ord k => NEMap k a -> k -> Maybe a
- Data.Map.NonEmpty: (\\) :: Ord k => NEMap k a -> NEMap k b -> Map k a
- Data.Map.NonEmpty: absurdNEMap :: NEMap Void a -> b
- Data.Map.NonEmpty: adjust :: Ord k => (a -> a) -> k -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: adjustAt :: (k -> a -> a) -> Int -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: adjustMax :: (a -> a) -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: adjustMaxWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: adjustMin :: (a -> a) -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: adjustMinWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: adjustWithKey :: Ord k => (k -> a -> a) -> k -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: alter :: Ord k => (Maybe a -> Maybe a) -> k -> NEMap k a -> Map k a
- Data.Map.NonEmpty: alter' :: Ord k => (Maybe a -> a) -> k -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: alterF :: (Ord k, Functor f) => (Maybe a -> f (Maybe a)) -> k -> NEMap k a -> f (Map k a)
- Data.Map.NonEmpty: alterF' :: (Ord k, Functor f) => (Maybe a -> f a) -> k -> NEMap k a -> f (NEMap k a)
- Data.Map.NonEmpty: assocs :: NEMap k a -> NonEmpty (k, a)
- Data.Map.NonEmpty: data NEMap k a
- Data.Map.NonEmpty: delete :: Ord k => k -> NEMap k a -> Map k a
- Data.Map.NonEmpty: deleteAt :: Int -> NEMap k a -> Map k a
- Data.Map.NonEmpty: deleteFindMax :: NEMap k a -> ((k, a), Map k a)
- Data.Map.NonEmpty: deleteFindMin :: NEMap k a -> ((k, a), Map k a)
- Data.Map.NonEmpty: deleteMax :: NEMap k a -> Map k a
- Data.Map.NonEmpty: deleteMaybe :: Ord k => k -> NEMap k a -> Maybe (NEMap k a)
- Data.Map.NonEmpty: deleteMin :: NEMap k a -> Map k a
- Data.Map.NonEmpty: difference :: Ord k => NEMap k a -> NEMap k b -> Map k a
- Data.Map.NonEmpty: differenceWith :: Ord k => (a -> b -> Maybe a) -> NEMap k a -> NEMap k b -> Map k a
- Data.Map.NonEmpty: differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> NEMap k a -> NEMap k b -> Map k a
- Data.Map.NonEmpty: drop :: Int -> NEMap k a -> Map k a
- Data.Map.NonEmpty: dropWhileAntitone :: (k -> Bool) -> NEMap k a -> Map k a
- Data.Map.NonEmpty: elemAt :: Int -> NEMap k a -> (k, a)
- Data.Map.NonEmpty: elems :: NEMap k a -> NonEmpty a
- Data.Map.NonEmpty: filter :: (a -> Bool) -> NEMap k a -> Map k a
- Data.Map.NonEmpty: filterWithKey :: (k -> a -> Bool) -> NEMap k a -> Map k a
- Data.Map.NonEmpty: findIndex :: Ord k => k -> NEMap k a -> Int
- Data.Map.NonEmpty: findMax :: NEMap k a -> (k, a)
- Data.Map.NonEmpty: findMin :: NEMap k a -> (k, a)
- Data.Map.NonEmpty: findWithDefault :: Ord k => a -> k -> NEMap k a -> a
- Data.Map.NonEmpty: foldMapWithKey :: Semigroup m => (k -> a -> m) -> NEMap k a -> m
- Data.Map.NonEmpty: foldl :: (a -> b -> a) -> a -> NEMap k b -> a
- Data.Map.NonEmpty: foldl' :: (a -> b -> a) -> a -> NEMap k b -> a
- Data.Map.NonEmpty: foldl1 :: (a -> a -> a) -> NEMap k a -> a
- Data.Map.NonEmpty: foldl1' :: (a -> a -> a) -> NEMap k a -> a
- Data.Map.NonEmpty: foldlWithKey :: (a -> k -> b -> a) -> a -> NEMap k b -> a
- Data.Map.NonEmpty: foldlWithKey' :: (a -> k -> b -> a) -> a -> NEMap k b -> a
- Data.Map.NonEmpty: foldr :: (a -> b -> b) -> b -> NEMap k a -> b
- Data.Map.NonEmpty: foldr' :: (a -> b -> b) -> b -> NEMap k a -> b
- Data.Map.NonEmpty: foldr1 :: (a -> a -> a) -> NEMap k a -> a
- Data.Map.NonEmpty: foldr1' :: (a -> a -> a) -> NEMap k a -> a
- Data.Map.NonEmpty: foldrWithKey :: (k -> a -> b -> b) -> b -> NEMap k a -> b
- Data.Map.NonEmpty: foldrWithKey' :: (k -> a -> b -> b) -> b -> NEMap k a -> b
- Data.Map.NonEmpty: fromAscList :: Eq k => NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromAscListWith :: Eq k => (a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromDescList :: Eq k => NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromDescListWith :: Eq k => (a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromDistinctAscList :: NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromDistinctDescList :: NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromList :: Ord k => NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromListWith :: Ord k => (a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromListWithKey :: Ord k => (k -> a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty: fromSet :: (k -> a) -> NESet k -> NEMap k a
- Data.Map.NonEmpty: infixl 9 !
- Data.Map.NonEmpty: insert :: Ord k => k -> a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> NEMap k a -> (Maybe a, NEMap k a)
- Data.Map.NonEmpty: insertMap :: Ord k => k -> a -> Map k a -> NEMap k a
- Data.Map.NonEmpty: insertMapMax :: k -> a -> Map k a -> NEMap k a
- Data.Map.NonEmpty: insertMapMin :: k -> a -> Map k a -> NEMap k a
- Data.Map.NonEmpty: insertMapWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> NEMap k a
- Data.Map.NonEmpty: insertMapWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> NEMap k a
- Data.Map.NonEmpty: insertWith :: Ord k => (a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: intersection :: Ord k => NEMap k a -> NEMap k b -> Map k a
- Data.Map.NonEmpty: intersectionWith :: Ord k => (a -> b -> c) -> NEMap k a -> NEMap k b -> Map k c
- Data.Map.NonEmpty: intersectionWithKey :: Ord k => (k -> a -> b -> c) -> NEMap k a -> NEMap k b -> Map k c
- Data.Map.NonEmpty: isProperSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool
- Data.Map.NonEmpty: isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> NEMap k a -> NEMap k b -> Bool
- Data.Map.NonEmpty: isSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool
- Data.Map.NonEmpty: isSubmapOfBy :: Ord k => (a -> b -> Bool) -> NEMap k a -> NEMap k b -> Bool
- Data.Map.NonEmpty: keys :: NEMap k a -> NonEmpty k
- Data.Map.NonEmpty: keysSet :: NEMap k a -> NESet k
- Data.Map.NonEmpty: lookup :: Ord k => k -> NEMap k a -> Maybe a
- Data.Map.NonEmpty: lookupGE :: Ord k => k -> NEMap k a -> Maybe (k, a)
- Data.Map.NonEmpty: lookupGT :: Ord k => k -> NEMap k a -> Maybe (k, a)
- Data.Map.NonEmpty: lookupIndex :: Ord k => k -> NEMap k a -> Maybe Int
- Data.Map.NonEmpty: lookupLE :: Ord k => k -> NEMap k a -> Maybe (k, a)
- Data.Map.NonEmpty: lookupLT :: Ord k => k -> NEMap k a -> Maybe (k, a)
- Data.Map.NonEmpty: map :: (a -> b) -> NEMap k a -> NEMap k b
- Data.Map.NonEmpty: mapAccum :: (a -> b -> (a, c)) -> a -> NEMap k b -> (a, NEMap k c)
- Data.Map.NonEmpty: mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> NEMap k b -> (a, NEMap k c)
- Data.Map.NonEmpty: mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> NEMap k b -> (a, NEMap k c)
- Data.Map.NonEmpty: mapEither :: (a -> Either b c) -> NEMap k a -> These (NEMap k b) (NEMap k c)
- Data.Map.NonEmpty: mapEitherWithKey :: (k -> a -> Either b c) -> NEMap k a -> These (NEMap k b) (NEMap k c)
- Data.Map.NonEmpty: mapKeys :: Ord k2 => (k1 -> k2) -> NEMap k1 a -> NEMap k2 a
- Data.Map.NonEmpty: mapKeysMonotonic :: (k1 -> k2) -> NEMap k1 a -> NEMap k2 a
- Data.Map.NonEmpty: mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> NEMap k1 a -> NEMap k2 a
- Data.Map.NonEmpty: mapMaybe :: (a -> Maybe b) -> NEMap k a -> Map k b
- Data.Map.NonEmpty: mapMaybeWithKey :: (k -> a -> Maybe b) -> NEMap k a -> Map k b
- Data.Map.NonEmpty: mapWithKey :: (k -> a -> b) -> NEMap k a -> NEMap k b
- Data.Map.NonEmpty: maxView :: NEMap k a -> (a, Map k a)
- Data.Map.NonEmpty: member :: Ord k => k -> NEMap k a -> Bool
- Data.Map.NonEmpty: minView :: NEMap k a -> (a, Map k a)
- Data.Map.NonEmpty: nonEmptyMap :: Map k a -> Maybe (NEMap k a)
- Data.Map.NonEmpty: notMember :: Ord k => k -> NEMap k a -> Bool
- Data.Map.NonEmpty: partition :: (a -> Bool) -> NEMap k a -> These (NEMap k a) (NEMap k a)
- Data.Map.NonEmpty: partitionWithKey :: (k -> a -> Bool) -> NEMap k a -> These (NEMap k a) (NEMap k a)
- Data.Map.NonEmpty: pattern IsEmpty :: Map k a
- Data.Map.NonEmpty: pattern IsNonEmpty :: NEMap k a -> Map k a
- Data.Map.NonEmpty: restrictKeys :: Ord k => NEMap k a -> Set k -> Map k a
- Data.Map.NonEmpty: singleton :: k -> a -> NEMap k a
- Data.Map.NonEmpty: size :: NEMap k a -> Int
- Data.Map.NonEmpty: spanAntitone :: (k -> Bool) -> NEMap k a -> These (NEMap k a) (NEMap k a)
- Data.Map.NonEmpty: split :: Ord k => k -> NEMap k a -> Maybe (These (NEMap k a) (NEMap k a))
- Data.Map.NonEmpty: splitAt :: Int -> NEMap k a -> These (NEMap k a) (NEMap k a)
- Data.Map.NonEmpty: splitLookup :: Ord k => k -> NEMap k a -> These a (These (NEMap k a) (NEMap k a))
- Data.Map.NonEmpty: splitRoot :: NEMap k a -> NonEmpty (NEMap k a)
- Data.Map.NonEmpty: take :: Int -> NEMap k a -> Map k a
- Data.Map.NonEmpty: takeWhileAntitone :: (k -> Bool) -> NEMap k a -> Map k a
- Data.Map.NonEmpty: toAscList :: NEMap k a -> NonEmpty (k, a)
- Data.Map.NonEmpty: toDescList :: NEMap k a -> NonEmpty (k, a)
- Data.Map.NonEmpty: toList :: NEMap k a -> NonEmpty (k, a)
- Data.Map.NonEmpty: toMap :: NEMap k a -> Map k a
- Data.Map.NonEmpty: traverseMaybeWithKey :: Applicative t => (k -> a -> t (Maybe b)) -> NEMap k a -> t (Map k b)
- Data.Map.NonEmpty: traverseMaybeWithKey1 :: Apply t => (k -> a -> t (Maybe b)) -> NEMap k a -> t (Map k b)
- Data.Map.NonEmpty: traverseWithKey :: Applicative t => (k -> a -> t b) -> NEMap k a -> t (NEMap k b)
- Data.Map.NonEmpty: traverseWithKey1 :: Apply t => (k -> a -> t b) -> NEMap k a -> t (NEMap k b)
- Data.Map.NonEmpty: union :: Ord k => NEMap k a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: unionMapLeft :: Ord k => Map k a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: unionMapRight :: Ord k => NEMap k a -> Map k a -> NEMap k a
- Data.Map.NonEmpty: unionMapWithKeyLeft :: Ord k => (k -> a -> a -> a) -> Map k a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: unionMapWithKeyRight :: Ord k => (k -> a -> a -> a) -> NEMap k a -> Map k a -> NEMap k a
- Data.Map.NonEmpty: unionMapWithLeft :: Ord k => (a -> a -> a) -> Map k a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: unionMapWithRight :: Ord k => (a -> a -> a) -> NEMap k a -> Map k a -> NEMap k a
- Data.Map.NonEmpty: unionWith :: Ord k => (a -> a -> a) -> NEMap k a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: unionWithKey :: Ord k => (k -> a -> a -> a) -> NEMap k a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty: unions :: (Foldable1 f, Ord k) => f (NEMap k a) -> NEMap k a
- Data.Map.NonEmpty: unionsWith :: (Foldable1 f, Ord k) => (a -> a -> a) -> f (NEMap k a) -> NEMap k a
- Data.Map.NonEmpty: unsafeFromMap :: Map k a -> NEMap k a
- Data.Map.NonEmpty: update :: Ord k => (a -> Maybe a) -> k -> NEMap k a -> Map k a
- Data.Map.NonEmpty: updateAt :: (k -> a -> Maybe a) -> Int -> NEMap k a -> Map k a
- Data.Map.NonEmpty: updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> NEMap k a -> (Maybe a, Map k a)
- Data.Map.NonEmpty: updateMax :: (a -> Maybe a) -> NEMap k a -> Map k a
- Data.Map.NonEmpty: updateMaxWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a
- Data.Map.NonEmpty: updateMin :: (a -> Maybe a) -> NEMap k a -> Map k a
- Data.Map.NonEmpty: updateMinWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a
- Data.Map.NonEmpty: updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> NEMap k a -> Map k a
- Data.Map.NonEmpty: valid :: Ord k => NEMap k a -> Bool
- Data.Map.NonEmpty: withNonEmpty :: r -> (NEMap k a -> r) -> Map k a -> r
- Data.Map.NonEmpty: withoutKeys :: Ord k => NEMap k a -> Set k -> Map k a
- Data.Map.NonEmpty.Internal: NEMap :: !k -> a -> !Map k a -> NEMap k a
- Data.Map.NonEmpty.Internal: [nemK0] :: NEMap k a -> !k
- Data.Map.NonEmpty.Internal: [nemMap] :: NEMap k a -> !Map k a
- Data.Map.NonEmpty.Internal: [nemV0] :: NEMap k a -> a
- Data.Map.NonEmpty.Internal: data NEMap k a
- Data.Map.NonEmpty.Internal: elems :: NEMap k a -> NonEmpty a
- Data.Map.NonEmpty.Internal: foldMapWithKey :: Semigroup m => (k -> a -> m) -> NEMap k a -> m
- Data.Map.NonEmpty.Internal: foldl :: (a -> b -> a) -> a -> NEMap k b -> a
- Data.Map.NonEmpty.Internal: foldl' :: (a -> b -> a) -> a -> NEMap k b -> a
- Data.Map.NonEmpty.Internal: foldl1 :: (a -> a -> a) -> NEMap k a -> a
- Data.Map.NonEmpty.Internal: foldr :: (a -> b -> b) -> b -> NEMap k a -> b
- Data.Map.NonEmpty.Internal: foldr' :: (a -> b -> b) -> b -> NEMap k a -> b
- Data.Map.NonEmpty.Internal: foldr1 :: (a -> a -> a) -> NEMap k a -> a
- Data.Map.NonEmpty.Internal: fromList :: Ord k => NonEmpty (k, a) -> NEMap k a
- Data.Map.NonEmpty.Internal: insertMaxMap :: k -> a -> Map k a -> Map k a
- Data.Map.NonEmpty.Internal: insertMinMap :: k -> a -> Map k a -> Map k a
- Data.Map.NonEmpty.Internal: insertWith :: Ord k => (a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty.Internal: instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.Map.NonEmpty.Internal: instance (Data.Aeson.Types.FromJSON.FromJSONKey k, GHC.Classes.Ord k, Data.Aeson.Types.FromJSON.FromJSON a) => Data.Aeson.Types.FromJSON.FromJSON (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.Map.NonEmpty.Internal: instance (Data.Aeson.Types.ToJSON.ToJSONKey k, Data.Aeson.Types.ToJSON.ToJSON a) => Data.Aeson.Types.ToJSON.ToJSON (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.Map.NonEmpty.Internal: instance (Data.Data.Data k, Data.Data.Data a, GHC.Classes.Ord k) => Data.Data.Data (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.Map.NonEmpty.Internal: instance (GHC.Classes.Eq k, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.Map.NonEmpty.Internal: instance (GHC.Classes.Ord k, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.Map.NonEmpty.Internal: instance (GHC.Classes.Ord k, GHC.Read.Read k) => Data.Functor.Classes.Read1 (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance (GHC.Classes.Ord k, GHC.Read.Read k, GHC.Read.Read e) => GHC.Read.Read (Data.Map.NonEmpty.Internal.NEMap k e)
- Data.Map.NonEmpty.Internal: instance (GHC.Show.Show k, GHC.Show.Show a) => GHC.Show.Show (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.Map.NonEmpty.Internal: instance Control.Comonad.Comonad (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance Data.Foldable.Foldable (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance Data.Foldable1.Foldable1 (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance Data.Functor.Classes.Eq2 Data.Map.NonEmpty.Internal.NEMap
- Data.Map.NonEmpty.Internal: instance Data.Functor.Classes.Ord2 Data.Map.NonEmpty.Internal.NEMap
- Data.Map.NonEmpty.Internal: instance Data.Functor.Classes.Show2 Data.Map.NonEmpty.Internal.NEMap
- Data.Map.NonEmpty.Internal: instance Data.Functor.Invariant.Invariant (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance Data.Semigroup.Traversable.Class.Traversable1 (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance Data.Traversable.Traversable (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance GHC.Base.Functor (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance GHC.Classes.Eq k => Data.Functor.Classes.Eq1 (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance GHC.Classes.Ord k => Data.Functor.Alt.Alt (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance GHC.Classes.Ord k => Data.Functor.Classes.Ord1 (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance GHC.Classes.Ord k => GHC.Base.Semigroup (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.Map.NonEmpty.Internal: instance GHC.Classes.Ord k => GHC.IsList.IsList (Data.Map.NonEmpty.Internal.NEMap k a)
- Data.Map.NonEmpty.Internal: instance GHC.Show.Show k => Data.Functor.Classes.Show1 (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance WithIndex.FoldableWithIndex k (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance WithIndex.FunctorWithIndex k (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: instance WithIndex.TraversableWithIndex k (Data.Map.NonEmpty.Internal.NEMap k)
- Data.Map.NonEmpty.Internal: map :: (a -> b) -> NEMap k a -> NEMap k b
- Data.Map.NonEmpty.Internal: nonEmptyMap :: Map k a -> Maybe (NEMap k a)
- Data.Map.NonEmpty.Internal: singleton :: k -> a -> NEMap k a
- Data.Map.NonEmpty.Internal: size :: NEMap k a -> Int
- Data.Map.NonEmpty.Internal: toList :: NEMap k a -> NonEmpty (k, a)
- Data.Map.NonEmpty.Internal: toMap :: NEMap k a -> Map k a
- Data.Map.NonEmpty.Internal: traverseWithKey :: Applicative t => (k -> a -> t b) -> NEMap k a -> t (NEMap k b)
- Data.Map.NonEmpty.Internal: traverseWithKey1 :: Apply t => (k -> a -> t b) -> NEMap k a -> t (NEMap k b)
- Data.Map.NonEmpty.Internal: union :: Ord k => NEMap k a -> NEMap k a -> NEMap k a
- Data.Map.NonEmpty.Internal: unions :: (Foldable1 f, Ord k) => f (NEMap k a) -> NEMap k a
- Data.Map.NonEmpty.Internal: valid :: Ord k => NEMap k a -> Bool
- Data.Map.NonEmpty.Internal: withNonEmpty :: r -> (NEMap k a -> r) -> Map k a -> r
+ Data.Containers.NonEmpty.List: instance Data.Containers.NonEmpty.List.IsNonEmptyList (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.Containers.NonEmpty.List: instance GHC.Classes.Ord k => Data.Containers.NonEmpty.List.IsNonEmptyList (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.IntMap.NonEmpty.Lazy: (!) :: NEIntMap a -> Key -> a
+ Data.IntMap.NonEmpty.Lazy: (!?) :: NEIntMap a -> Key -> Maybe a
+ Data.IntMap.NonEmpty.Lazy: (\\) :: NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: adjust :: (a -> a) -> Key -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: adjustMax :: (a -> a) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: adjustMaxWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: adjustMin :: (a -> a) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: adjustMinWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: adjustWithKey :: (Key -> a -> a) -> Key -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: alter :: (Maybe a -> Maybe a) -> Key -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: alter' :: (Maybe a -> a) -> Key -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> NEIntMap a -> f (IntMap a)
+ Data.IntMap.NonEmpty.Lazy: alterF' :: Functor f => (Maybe a -> f a) -> Key -> NEIntMap a -> f (NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy: assocs :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Lazy: data NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: delete :: Key -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: deleteFindMax :: NEIntMap a -> ((Key, a), IntMap a)
+ Data.IntMap.NonEmpty.Lazy: deleteFindMin :: NEIntMap a -> ((Key, a), IntMap a)
+ Data.IntMap.NonEmpty.Lazy: deleteMax :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: deleteMaybe :: Key -> NEIntMap a -> Maybe (NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy: deleteMin :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: difference :: NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: differenceWith :: (a -> b -> Maybe a) -> NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: differenceWithKey :: (Key -> a -> b -> Maybe a) -> NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: elems :: NEIntMap a -> NonEmpty a
+ Data.IntMap.NonEmpty.Lazy: filter :: (a -> Bool) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: filterWithKey :: (Key -> a -> Bool) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: findMax :: NEIntMap a -> (Key, a)
+ Data.IntMap.NonEmpty.Lazy: findMin :: NEIntMap a -> (Key, a)
+ Data.IntMap.NonEmpty.Lazy: findWithDefault :: a -> Key -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Lazy: foldMapWithKey :: Semigroup m => (Key -> a -> m) -> NEIntMap a -> m
+ Data.IntMap.NonEmpty.Lazy: foldl :: (a -> b -> a) -> a -> NEIntMap b -> a
+ Data.IntMap.NonEmpty.Lazy: foldl' :: (a -> b -> a) -> a -> NEIntMap b -> a
+ Data.IntMap.NonEmpty.Lazy: foldl1 :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Lazy: foldl1' :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Lazy: foldlWithKey :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a
+ Data.IntMap.NonEmpty.Lazy: foldlWithKey' :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a
+ Data.IntMap.NonEmpty.Lazy: foldr :: (a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Lazy: foldr' :: (a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Lazy: foldr1 :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Lazy: foldr1' :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Lazy: foldrWithKey :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Lazy: foldrWithKey' :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Lazy: fromAscList :: NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: fromAscListWith :: (a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: fromAscListWithKey :: (Key -> a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: fromDistinctAscList :: NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: fromList :: NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: fromListWith :: (a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: fromListWithKey :: (Key -> a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: fromSet :: (Key -> a) -> NEIntSet -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: infixl 9 !
+ Data.IntMap.NonEmpty.Lazy: insert :: Key -> a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> NEIntMap a -> (Maybe a, NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy: insertMap :: Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: insertMapMax :: Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: insertMapMin :: Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: insertMapWith :: (a -> a -> a) -> Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: insertMapWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: insertWith :: (a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: intersection :: NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: intersectionWith :: (a -> b -> c) -> NEIntMap a -> NEIntMap b -> IntMap c
+ Data.IntMap.NonEmpty.Lazy: intersectionWithKey :: (Key -> a -> b -> c) -> NEIntMap a -> NEIntMap b -> IntMap c
+ Data.IntMap.NonEmpty.Lazy: isProperSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Lazy: isProperSubmapOfBy :: (a -> b -> Bool) -> NEIntMap a -> NEIntMap b -> Bool
+ Data.IntMap.NonEmpty.Lazy: isSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Lazy: isSubmapOfBy :: (a -> b -> Bool) -> NEIntMap a -> NEIntMap b -> Bool
+ Data.IntMap.NonEmpty.Lazy: keys :: NEIntMap a -> NonEmpty Key
+ Data.IntMap.NonEmpty.Lazy: keysSet :: NEIntMap a -> NEIntSet
+ Data.IntMap.NonEmpty.Lazy: lookup :: Key -> NEIntMap a -> Maybe a
+ Data.IntMap.NonEmpty.Lazy: lookupGE :: Key -> NEIntMap a -> Maybe (Key, a)
+ Data.IntMap.NonEmpty.Lazy: lookupGT :: Key -> NEIntMap a -> Maybe (Key, a)
+ Data.IntMap.NonEmpty.Lazy: lookupLE :: Key -> NEIntMap a -> Maybe (Key, a)
+ Data.IntMap.NonEmpty.Lazy: lookupLT :: Key -> NEIntMap a -> Maybe (Key, a)
+ Data.IntMap.NonEmpty.Lazy: map :: (a -> b) -> NEIntMap a -> NEIntMap b
+ Data.IntMap.NonEmpty.Lazy: mapAccum :: (a -> b -> (a, c)) -> a -> NEIntMap b -> (a, NEIntMap c)
+ Data.IntMap.NonEmpty.Lazy: mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> NEIntMap b -> (a, NEIntMap c)
+ Data.IntMap.NonEmpty.Lazy: mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> NEIntMap b -> (a, NEIntMap c)
+ Data.IntMap.NonEmpty.Lazy: mapEither :: (a -> Either b c) -> NEIntMap a -> These (NEIntMap b) (NEIntMap c)
+ Data.IntMap.NonEmpty.Lazy: mapEitherWithKey :: (Key -> a -> Either b c) -> NEIntMap a -> These (NEIntMap b) (NEIntMap c)
+ Data.IntMap.NonEmpty.Lazy: mapKeys :: (Key -> Key) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: mapKeysMonotonic :: (Key -> Key) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: mapMaybe :: (a -> Maybe b) -> NEIntMap a -> IntMap b
+ Data.IntMap.NonEmpty.Lazy: mapMaybeWithKey :: (Key -> a -> Maybe b) -> NEIntMap a -> IntMap b
+ Data.IntMap.NonEmpty.Lazy: mapWithKey :: (Key -> a -> b) -> NEIntMap a -> NEIntMap b
+ Data.IntMap.NonEmpty.Lazy: maxView :: NEIntMap a -> (a, IntMap a)
+ Data.IntMap.NonEmpty.Lazy: member :: Key -> NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Lazy: minView :: NEIntMap a -> (a, IntMap a)
+ Data.IntMap.NonEmpty.Lazy: nonEmptyMap :: IntMap a -> Maybe (NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy: notMember :: Key -> NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Lazy: partition :: (a -> Bool) -> NEIntMap a -> These (NEIntMap a) (NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy: partitionWithKey :: (Key -> a -> Bool) -> NEIntMap a -> These (NEIntMap a) (NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy: pattern IsEmpty :: IntMap a
+ Data.IntMap.NonEmpty.Lazy: pattern IsNonEmpty :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: restrictKeys :: NEIntMap a -> IntSet -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: singleton :: Key -> a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: size :: NEIntMap a -> Int
+ Data.IntMap.NonEmpty.Lazy: split :: Key -> NEIntMap a -> Maybe (These (NEIntMap a) (NEIntMap a))
+ Data.IntMap.NonEmpty.Lazy: splitLookup :: Key -> NEIntMap a -> These a (These (NEIntMap a) (NEIntMap a))
+ Data.IntMap.NonEmpty.Lazy: splitRoot :: NEIntMap a -> NonEmpty (NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy: toAscList :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Lazy: toDescList :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Lazy: toList :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Lazy: toMap :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: traverseWithKey :: Applicative t => (Key -> a -> t b) -> NEIntMap a -> t (NEIntMap b)
+ Data.IntMap.NonEmpty.Lazy: traverseWithKey1 :: Apply t => (Key -> a -> t b) -> NEIntMap a -> t (NEIntMap b)
+ Data.IntMap.NonEmpty.Lazy: type Key = Int
+ Data.IntMap.NonEmpty.Lazy: union :: NEIntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unionMapLeft :: IntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unionMapRight :: NEIntMap a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unionMapWithKeyLeft :: (Key -> a -> a -> a) -> IntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unionMapWithKeyRight :: (Key -> a -> a -> a) -> NEIntMap a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unionMapWithLeft :: (a -> a -> a) -> IntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unionMapWithRight :: (a -> a -> a) -> NEIntMap a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unionWith :: (a -> a -> a) -> NEIntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unionWithKey :: (Key -> a -> a -> a) -> NEIntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unions :: Foldable1 f => f (NEIntMap a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unionsWith :: Foldable1 f => (a -> a -> a) -> f (NEIntMap a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: unsafeFromMap :: IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy: update :: (a -> Maybe a) -> Key -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> NEIntMap a -> (Maybe a, IntMap a)
+ Data.IntMap.NonEmpty.Lazy: updateMax :: (a -> Maybe a) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: updateMaxWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: updateMin :: (a -> Maybe a) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: updateMinWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: updateWithKey :: (Key -> a -> Maybe a) -> Key -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy: valid :: NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Lazy: withNonEmpty :: r -> (NEIntMap a -> r) -> IntMap a -> r
+ Data.IntMap.NonEmpty.Lazy: withoutKeys :: NEIntMap a -> IntSet -> IntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: NEIntMap :: !Key -> a -> !IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: [neimIntMap] :: NEIntMap a -> !IntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: [neimK0] :: NEIntMap a -> !Key
+ Data.IntMap.NonEmpty.Lazy.Internal: [neimV0] :: NEIntMap a -> a
+ Data.IntMap.NonEmpty.Lazy.Internal: data NEIntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: elems :: NEIntMap a -> NonEmpty a
+ Data.IntMap.NonEmpty.Lazy.Internal: foldMapWithKey :: Semigroup m => (Key -> a -> m) -> NEIntMap a -> m
+ Data.IntMap.NonEmpty.Lazy.Internal: foldl :: (a -> b -> a) -> a -> NEIntMap b -> a
+ Data.IntMap.NonEmpty.Lazy.Internal: foldl' :: (a -> b -> a) -> a -> NEIntMap b -> a
+ Data.IntMap.NonEmpty.Lazy.Internal: foldl1 :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Lazy.Internal: foldr :: (a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Lazy.Internal: foldr' :: (a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Lazy.Internal: foldr1 :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Lazy.Internal: fromList :: NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: insertMaxMap :: Key -> a -> IntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: insertMinMap :: Key -> a -> IntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: insertWith :: (a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Control.Comonad.Comonad Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Data.Data a => Data.Data.Data (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Foldable.Foldable Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Foldable1.Foldable1 Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Functor.Alt.Alt Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Functor.Classes.Eq1 Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Functor.Classes.Ord1 Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Functor.Classes.Read1 Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Functor.Classes.Show1 Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Functor.Invariant.Invariant Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Semigroup.Traversable.Class.Traversable1 Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance Data.Traversable.Traversable Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance GHC.Base.Functor Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance GHC.Base.Semigroup (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance GHC.IsList.IsList (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance GHC.Read.Read e => GHC.Read.Read (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap e)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance GHC.Show.Show a => GHC.Show.Show (Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: instance WithIndex.FoldableWithIndex GHC.Types.Int Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance WithIndex.FunctorWithIndex GHC.Types.Int Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: instance WithIndex.TraversableWithIndex GHC.Types.Int Data.IntMap.NonEmpty.Lazy.Internal.NEIntMap
+ Data.IntMap.NonEmpty.Lazy.Internal: map :: (a -> b) -> NEIntMap a -> NEIntMap b
+ Data.IntMap.NonEmpty.Lazy.Internal: nonEmptyMap :: IntMap a -> Maybe (NEIntMap a)
+ Data.IntMap.NonEmpty.Lazy.Internal: singleton :: Key -> a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: size :: NEIntMap a -> Int
+ Data.IntMap.NonEmpty.Lazy.Internal: toList :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Lazy.Internal: toMap :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: traverseWithKey :: Applicative t => (Key -> a -> t b) -> NEIntMap a -> t (NEIntMap b)
+ Data.IntMap.NonEmpty.Lazy.Internal: traverseWithKey1 :: Apply t => (Key -> a -> t b) -> NEIntMap a -> t (NEIntMap b)
+ Data.IntMap.NonEmpty.Lazy.Internal: type Key = Int
+ Data.IntMap.NonEmpty.Lazy.Internal: union :: NEIntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: unions :: Foldable1 f => f (NEIntMap a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Lazy.Internal: valid :: NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Lazy.Internal: withNonEmpty :: r -> (NEIntMap a -> r) -> IntMap a -> r
+ Data.IntMap.NonEmpty.Strict: (!) :: NEIntMap a -> Key -> a
+ Data.IntMap.NonEmpty.Strict: (!?) :: NEIntMap a -> Key -> Maybe a
+ Data.IntMap.NonEmpty.Strict: (\\) :: NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Strict: adjust :: (a -> a) -> Key -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: adjustMax :: (a -> a) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: adjustMaxWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: adjustMin :: (a -> a) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: adjustMinWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: adjustWithKey :: (Key -> a -> a) -> Key -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: alter :: (Maybe a -> Maybe a) -> Key -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: alter' :: (Maybe a -> a) -> Key -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> NEIntMap a -> f (IntMap a)
+ Data.IntMap.NonEmpty.Strict: alterF' :: Functor f => (Maybe a -> f a) -> Key -> NEIntMap a -> f (NEIntMap a)
+ Data.IntMap.NonEmpty.Strict: assocs :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Strict: delete :: Key -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: deleteFindMax :: NEIntMap a -> ((Key, a), IntMap a)
+ Data.IntMap.NonEmpty.Strict: deleteFindMin :: NEIntMap a -> ((Key, a), IntMap a)
+ Data.IntMap.NonEmpty.Strict: deleteMax :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: deleteMaybe :: Key -> NEIntMap a -> Maybe (NEIntMap a)
+ Data.IntMap.NonEmpty.Strict: deleteMin :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: difference :: NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Strict: differenceWith :: (a -> b -> Maybe a) -> NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Strict: differenceWithKey :: (Key -> a -> b -> Maybe a) -> NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Strict: elems :: NEIntMap a -> NonEmpty a
+ Data.IntMap.NonEmpty.Strict: filter :: (a -> Bool) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: filterWithKey :: (Key -> a -> Bool) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: findMax :: NEIntMap a -> (Key, a)
+ Data.IntMap.NonEmpty.Strict: findMin :: NEIntMap a -> (Key, a)
+ Data.IntMap.NonEmpty.Strict: findWithDefault :: a -> Key -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Strict: foldMapWithKey :: Monoid m => (Key -> a -> m) -> NEIntMap a -> m
+ Data.IntMap.NonEmpty.Strict: foldl :: (b -> a -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict: foldl' :: (b -> a -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict: foldl1 :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Strict: foldl1' :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Strict: foldlWithKey :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a
+ Data.IntMap.NonEmpty.Strict: foldlWithKey' :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a
+ Data.IntMap.NonEmpty.Strict: foldr :: (a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict: foldr' :: (a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict: foldr1 :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Strict: foldr1' :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Strict: foldrWithKey :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict: foldrWithKey' :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict: fromAscList :: NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: fromAscListWith :: (a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: fromAscListWithKey :: (Key -> a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: fromDistinctAscList :: NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: fromList :: NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: fromListWith :: (a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: fromListWithKey :: (Key -> a -> a -> a) -> NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: fromSet :: (Key -> a) -> NEIntSet -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: infixl 9 !
+ Data.IntMap.NonEmpty.Strict: insert :: Key -> a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> NEIntMap a -> (Maybe a, NEIntMap a)
+ Data.IntMap.NonEmpty.Strict: insertMap :: Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: insertMapMax :: Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: insertMapMin :: Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: insertMapWith :: (a -> a -> a) -> Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: insertMapWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: insertWith :: (a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: intersection :: NEIntMap a -> NEIntMap b -> IntMap a
+ Data.IntMap.NonEmpty.Strict: intersectionWith :: (a -> b -> c) -> NEIntMap a -> NEIntMap b -> IntMap c
+ Data.IntMap.NonEmpty.Strict: intersectionWithKey :: (Key -> a -> b -> c) -> NEIntMap a -> NEIntMap b -> IntMap c
+ Data.IntMap.NonEmpty.Strict: isProperSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Strict: isProperSubmapOfBy :: (a -> b -> Bool) -> NEIntMap a -> NEIntMap b -> Bool
+ Data.IntMap.NonEmpty.Strict: isSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Strict: isSubmapOfBy :: (a -> b -> Bool) -> NEIntMap a -> NEIntMap b -> Bool
+ Data.IntMap.NonEmpty.Strict: keys :: NEIntMap a -> NonEmpty Key
+ Data.IntMap.NonEmpty.Strict: keysSet :: NEIntMap a -> NEIntSet
+ Data.IntMap.NonEmpty.Strict: lookup :: Key -> NEIntMap a -> Maybe a
+ Data.IntMap.NonEmpty.Strict: lookupGE :: Key -> NEIntMap a -> Maybe (Key, a)
+ Data.IntMap.NonEmpty.Strict: lookupGT :: Key -> NEIntMap a -> Maybe (Key, a)
+ Data.IntMap.NonEmpty.Strict: lookupLE :: Key -> NEIntMap a -> Maybe (Key, a)
+ Data.IntMap.NonEmpty.Strict: lookupLT :: Key -> NEIntMap a -> Maybe (Key, a)
+ Data.IntMap.NonEmpty.Strict: map :: (a -> b) -> NEIntMap a -> NEIntMap b
+ Data.IntMap.NonEmpty.Strict: mapAccum :: (a -> b -> (a, c)) -> a -> NEIntMap b -> (a, NEIntMap c)
+ Data.IntMap.NonEmpty.Strict: mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> NEIntMap b -> (a, NEIntMap c)
+ Data.IntMap.NonEmpty.Strict: mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> NEIntMap b -> (a, NEIntMap c)
+ Data.IntMap.NonEmpty.Strict: mapEither :: (a -> Either b c) -> NEIntMap a -> These (NEIntMap b) (NEIntMap c)
+ Data.IntMap.NonEmpty.Strict: mapEitherWithKey :: (Key -> a -> Either b c) -> NEIntMap a -> These (NEIntMap b) (NEIntMap c)
+ Data.IntMap.NonEmpty.Strict: mapKeys :: (Key -> Key) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: mapKeysMonotonic :: (Key -> Key) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: mapMaybe :: (a -> Maybe b) -> NEIntMap a -> IntMap b
+ Data.IntMap.NonEmpty.Strict: mapMaybeWithKey :: (Key -> a -> Maybe b) -> NEIntMap a -> IntMap b
+ Data.IntMap.NonEmpty.Strict: mapWithKey :: (Key -> a -> b) -> NEIntMap a -> NEIntMap b
+ Data.IntMap.NonEmpty.Strict: maxView :: NEIntMap a -> (a, IntMap a)
+ Data.IntMap.NonEmpty.Strict: member :: Key -> NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Strict: minView :: NEIntMap a -> (a, IntMap a)
+ Data.IntMap.NonEmpty.Strict: nonEmptyMap :: IntMap a -> Maybe (NEIntMap a)
+ Data.IntMap.NonEmpty.Strict: notMember :: Key -> NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Strict: partition :: (a -> Bool) -> NEIntMap a -> These (NEIntMap a) (NEIntMap a)
+ Data.IntMap.NonEmpty.Strict: partitionWithKey :: (Key -> a -> Bool) -> NEIntMap a -> These (NEIntMap a) (NEIntMap a)
+ Data.IntMap.NonEmpty.Strict: pattern IsEmpty :: IntMap a
+ Data.IntMap.NonEmpty.Strict: pattern IsNonEmpty :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: restrictKeys :: NEIntMap a -> IntSet -> IntMap a
+ Data.IntMap.NonEmpty.Strict: singleton :: Key -> a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: size :: NEIntMap a -> Int
+ Data.IntMap.NonEmpty.Strict: split :: Key -> NEIntMap a -> Maybe (These (NEIntMap a) (NEIntMap a))
+ Data.IntMap.NonEmpty.Strict: splitLookup :: Key -> NEIntMap a -> These a (These (NEIntMap a) (NEIntMap a))
+ Data.IntMap.NonEmpty.Strict: splitRoot :: NEIntMap a -> NonEmpty (NEIntMap a)
+ Data.IntMap.NonEmpty.Strict: toAscList :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Strict: toDescList :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Strict: toList :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Strict: toMap :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: traverseWithKey :: Applicative f => (Key -> a -> f b) -> NEIntMap a -> f (NEIntMap b)
+ Data.IntMap.NonEmpty.Strict: traverseWithKey1 :: Apply f => (Key -> a -> f b) -> NEIntMap a -> f (NEIntMap b)
+ Data.IntMap.NonEmpty.Strict: type Key = Int
+ Data.IntMap.NonEmpty.Strict: type NEIntMap = NEIntMap
+ Data.IntMap.NonEmpty.Strict: union :: NEIntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unionMapLeft :: IntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unionMapRight :: NEIntMap a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unionMapWithKeyLeft :: (Key -> a -> a -> a) -> IntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unionMapWithKeyRight :: (Key -> a -> a -> a) -> NEIntMap a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unionMapWithLeft :: (a -> a -> a) -> IntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unionMapWithRight :: (a -> a -> a) -> NEIntMap a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unionWith :: (a -> a -> a) -> NEIntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unionWithKey :: (Key -> a -> a -> a) -> NEIntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unions :: Foldable1 f => f (NEIntMap a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unionsWith :: Foldable1 f => (a -> a -> a) -> f (NEIntMap a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: unsafeFromMap :: IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict: update :: (a -> Maybe a) -> Key -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> NEIntMap a -> (Maybe a, IntMap a)
+ Data.IntMap.NonEmpty.Strict: updateMax :: (a -> Maybe a) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: updateMaxWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: updateMin :: (a -> Maybe a) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: updateMinWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: updateWithKey :: (Key -> a -> Maybe a) -> Key -> NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict: valid :: NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Strict: withNonEmpty :: b -> (NEIntMap a -> b) -> IntMap a -> b
+ Data.IntMap.NonEmpty.Strict: withoutKeys :: NEIntMap a -> IntSet -> IntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: elems :: NEIntMap a -> NonEmpty a
+ Data.IntMap.NonEmpty.Strict.Internal: foldMapWithKey :: Monoid m => (Key -> a -> m) -> NEIntMap a -> m
+ Data.IntMap.NonEmpty.Strict.Internal: foldl :: (b -> a -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict.Internal: foldl' :: (b -> a -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict.Internal: foldl1 :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Strict.Internal: foldr :: (a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict.Internal: foldr' :: (a -> b -> b) -> b -> NEIntMap a -> b
+ Data.IntMap.NonEmpty.Strict.Internal: foldr1 :: (a -> a -> a) -> NEIntMap a -> a
+ Data.IntMap.NonEmpty.Strict.Internal: fromList :: NonEmpty (Key, a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: insertMaxMap :: Key -> a -> IntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: insertMinMap :: Key -> a -> IntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: insertWith :: (a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: map :: (a -> b) -> NEIntMap a -> NEIntMap b
+ Data.IntMap.NonEmpty.Strict.Internal: neimIntMap :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: nonEmptyMap :: IntMap a -> Maybe (NEIntMap a)
+ Data.IntMap.NonEmpty.Strict.Internal: pattern NEIntMap :: Key -> a -> IntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: singleton :: Key -> a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: size :: NEIntMap a -> Int
+ Data.IntMap.NonEmpty.Strict.Internal: toList :: NEIntMap a -> NonEmpty (Key, a)
+ Data.IntMap.NonEmpty.Strict.Internal: toMap :: NEIntMap a -> IntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: traverseWithKey :: Applicative f => (Key -> a -> f b) -> NEIntMap a -> f (NEIntMap b)
+ Data.IntMap.NonEmpty.Strict.Internal: traverseWithKey1 :: Apply f => (Key -> a -> f b) -> NEIntMap a -> f (NEIntMap b)
+ Data.IntMap.NonEmpty.Strict.Internal: type Key = Int
+ Data.IntMap.NonEmpty.Strict.Internal: type NEIntMap = NEIntMap
+ Data.IntMap.NonEmpty.Strict.Internal: union :: NEIntMap a -> NEIntMap a -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: unions :: Foldable1 f => f (NEIntMap a) -> NEIntMap a
+ Data.IntMap.NonEmpty.Strict.Internal: valid :: NEIntMap a -> Bool
+ Data.IntMap.NonEmpty.Strict.Internal: withNonEmpty :: b -> (NEIntMap a -> b) -> IntMap a -> b
+ Data.Map.NonEmpty.Lazy: (!) :: Ord k => NEMap k a -> k -> a
+ Data.Map.NonEmpty.Lazy: (!?) :: Ord k => NEMap k a -> k -> Maybe a
+ Data.Map.NonEmpty.Lazy: (\\) :: Ord k => NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Lazy: absurdNEMap :: NEMap Void a -> b
+ Data.Map.NonEmpty.Lazy: adjust :: Ord k => (a -> a) -> k -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: adjustAt :: (k -> a -> a) -> Int -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: adjustMax :: (a -> a) -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: adjustMaxWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: adjustMin :: (a -> a) -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: adjustMinWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: adjustWithKey :: Ord k => (k -> a -> a) -> k -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: alter :: Ord k => (Maybe a -> Maybe a) -> k -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: alter' :: Ord k => (Maybe a -> a) -> k -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: alterF :: (Ord k, Functor f) => (Maybe a -> f (Maybe a)) -> k -> NEMap k a -> f (Map k a)
+ Data.Map.NonEmpty.Lazy: alterF' :: (Ord k, Functor f) => (Maybe a -> f a) -> k -> NEMap k a -> f (NEMap k a)
+ Data.Map.NonEmpty.Lazy: assocs :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Lazy: data NEMap k a
+ Data.Map.NonEmpty.Lazy: delete :: Ord k => k -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: deleteAt :: Int -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: deleteFindMax :: NEMap k a -> ((k, a), Map k a)
+ Data.Map.NonEmpty.Lazy: deleteFindMin :: NEMap k a -> ((k, a), Map k a)
+ Data.Map.NonEmpty.Lazy: deleteMax :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: deleteMaybe :: Ord k => k -> NEMap k a -> Maybe (NEMap k a)
+ Data.Map.NonEmpty.Lazy: deleteMin :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: difference :: Ord k => NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Lazy: differenceWith :: Ord k => (a -> b -> Maybe a) -> NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Lazy: differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Lazy: drop :: Int -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: dropWhileAntitone :: (k -> Bool) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: elemAt :: Int -> NEMap k a -> (k, a)
+ Data.Map.NonEmpty.Lazy: elems :: NEMap k a -> NonEmpty a
+ Data.Map.NonEmpty.Lazy: filter :: (a -> Bool) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: filterWithKey :: (k -> a -> Bool) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: findIndex :: Ord k => k -> NEMap k a -> Int
+ Data.Map.NonEmpty.Lazy: findMax :: NEMap k a -> (k, a)
+ Data.Map.NonEmpty.Lazy: findMin :: NEMap k a -> (k, a)
+ Data.Map.NonEmpty.Lazy: findWithDefault :: Ord k => a -> k -> NEMap k a -> a
+ Data.Map.NonEmpty.Lazy: foldMapWithKey :: Semigroup m => (k -> a -> m) -> NEMap k a -> m
+ Data.Map.NonEmpty.Lazy: foldl :: (a -> b -> a) -> a -> NEMap k b -> a
+ Data.Map.NonEmpty.Lazy: foldl' :: (a -> b -> a) -> a -> NEMap k b -> a
+ Data.Map.NonEmpty.Lazy: foldl1 :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Lazy: foldl1' :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Lazy: foldlWithKey :: (a -> k -> b -> a) -> a -> NEMap k b -> a
+ Data.Map.NonEmpty.Lazy: foldlWithKey' :: (a -> k -> b -> a) -> a -> NEMap k b -> a
+ Data.Map.NonEmpty.Lazy: foldr :: (a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Lazy: foldr' :: (a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Lazy: foldr1 :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Lazy: foldr1' :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Lazy: foldrWithKey :: (k -> a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Lazy: foldrWithKey' :: (k -> a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Lazy: fromAscList :: Eq k => NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromAscListWith :: Eq k => (a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromDescList :: Eq k => NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromDescListWith :: Eq k => (a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromDistinctAscList :: NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromDistinctDescList :: NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromList :: Ord k => NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromListWith :: Ord k => (a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromListWithKey :: Ord k => (k -> a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: fromSet :: (k -> a) -> NESet k -> NEMap k a
+ Data.Map.NonEmpty.Lazy: infixl 9 !
+ Data.Map.NonEmpty.Lazy: insert :: Ord k => k -> a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> NEMap k a -> (Maybe a, NEMap k a)
+ Data.Map.NonEmpty.Lazy: insertMap :: Ord k => k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: insertMapMax :: k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: insertMapMin :: k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: insertMapWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: insertMapWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: insertWith :: Ord k => (a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: intersection :: Ord k => NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Lazy: intersectionWith :: Ord k => (a -> b -> c) -> NEMap k a -> NEMap k b -> Map k c
+ Data.Map.NonEmpty.Lazy: intersectionWithKey :: Ord k => (k -> a -> b -> c) -> NEMap k a -> NEMap k b -> Map k c
+ Data.Map.NonEmpty.Lazy: isProperSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool
+ Data.Map.NonEmpty.Lazy: isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> NEMap k a -> NEMap k b -> Bool
+ Data.Map.NonEmpty.Lazy: isSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool
+ Data.Map.NonEmpty.Lazy: isSubmapOfBy :: Ord k => (a -> b -> Bool) -> NEMap k a -> NEMap k b -> Bool
+ Data.Map.NonEmpty.Lazy: keys :: NEMap k a -> NonEmpty k
+ Data.Map.NonEmpty.Lazy: keysSet :: NEMap k a -> NESet k
+ Data.Map.NonEmpty.Lazy: lookup :: Ord k => k -> NEMap k a -> Maybe a
+ Data.Map.NonEmpty.Lazy: lookupGE :: Ord k => k -> NEMap k a -> Maybe (k, a)
+ Data.Map.NonEmpty.Lazy: lookupGT :: Ord k => k -> NEMap k a -> Maybe (k, a)
+ Data.Map.NonEmpty.Lazy: lookupIndex :: Ord k => k -> NEMap k a -> Maybe Int
+ Data.Map.NonEmpty.Lazy: lookupLE :: Ord k => k -> NEMap k a -> Maybe (k, a)
+ Data.Map.NonEmpty.Lazy: lookupLT :: Ord k => k -> NEMap k a -> Maybe (k, a)
+ Data.Map.NonEmpty.Lazy: map :: (a -> b) -> NEMap k a -> NEMap k b
+ Data.Map.NonEmpty.Lazy: mapAccum :: (a -> b -> (a, c)) -> a -> NEMap k b -> (a, NEMap k c)
+ Data.Map.NonEmpty.Lazy: mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> NEMap k b -> (a, NEMap k c)
+ Data.Map.NonEmpty.Lazy: mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> NEMap k b -> (a, NEMap k c)
+ Data.Map.NonEmpty.Lazy: mapEither :: (a -> Either b c) -> NEMap k a -> These (NEMap k b) (NEMap k c)
+ Data.Map.NonEmpty.Lazy: mapEitherWithKey :: (k -> a -> Either b c) -> NEMap k a -> These (NEMap k b) (NEMap k c)
+ Data.Map.NonEmpty.Lazy: mapKeys :: Ord k2 => (k1 -> k2) -> NEMap k1 a -> NEMap k2 a
+ Data.Map.NonEmpty.Lazy: mapKeysMonotonic :: (k1 -> k2) -> NEMap k1 a -> NEMap k2 a
+ Data.Map.NonEmpty.Lazy: mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> NEMap k1 a -> NEMap k2 a
+ Data.Map.NonEmpty.Lazy: mapMaybe :: (a -> Maybe b) -> NEMap k a -> Map k b
+ Data.Map.NonEmpty.Lazy: mapMaybeWithKey :: (k -> a -> Maybe b) -> NEMap k a -> Map k b
+ Data.Map.NonEmpty.Lazy: mapWithKey :: (k -> a -> b) -> NEMap k a -> NEMap k b
+ Data.Map.NonEmpty.Lazy: maxView :: NEMap k a -> (a, Map k a)
+ Data.Map.NonEmpty.Lazy: member :: Ord k => k -> NEMap k a -> Bool
+ Data.Map.NonEmpty.Lazy: minView :: NEMap k a -> (a, Map k a)
+ Data.Map.NonEmpty.Lazy: nonEmptyMap :: Map k a -> Maybe (NEMap k a)
+ Data.Map.NonEmpty.Lazy: notMember :: Ord k => k -> NEMap k a -> Bool
+ Data.Map.NonEmpty.Lazy: partition :: (a -> Bool) -> NEMap k a -> These (NEMap k a) (NEMap k a)
+ Data.Map.NonEmpty.Lazy: partitionWithKey :: (k -> a -> Bool) -> NEMap k a -> These (NEMap k a) (NEMap k a)
+ Data.Map.NonEmpty.Lazy: pattern IsEmpty :: Map k a
+ Data.Map.NonEmpty.Lazy: pattern IsNonEmpty :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: restrictKeys :: Ord k => NEMap k a -> Set k -> Map k a
+ Data.Map.NonEmpty.Lazy: singleton :: k -> a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: size :: NEMap k a -> Int
+ Data.Map.NonEmpty.Lazy: spanAntitone :: (k -> Bool) -> NEMap k a -> These (NEMap k a) (NEMap k a)
+ Data.Map.NonEmpty.Lazy: split :: Ord k => k -> NEMap k a -> Maybe (These (NEMap k a) (NEMap k a))
+ Data.Map.NonEmpty.Lazy: splitAt :: Int -> NEMap k a -> These (NEMap k a) (NEMap k a)
+ Data.Map.NonEmpty.Lazy: splitLookup :: Ord k => k -> NEMap k a -> These a (These (NEMap k a) (NEMap k a))
+ Data.Map.NonEmpty.Lazy: splitRoot :: NEMap k a -> NonEmpty (NEMap k a)
+ Data.Map.NonEmpty.Lazy: take :: Int -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: takeWhileAntitone :: (k -> Bool) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: toAscList :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Lazy: toDescList :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Lazy: toList :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Lazy: toMap :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: traverseMaybeWithKey :: Applicative t => (k -> a -> t (Maybe b)) -> NEMap k a -> t (Map k b)
+ Data.Map.NonEmpty.Lazy: traverseMaybeWithKey1 :: Apply t => (k -> a -> t (Maybe b)) -> NEMap k a -> t (Map k b)
+ Data.Map.NonEmpty.Lazy: traverseWithKey :: Applicative t => (k -> a -> t b) -> NEMap k a -> t (NEMap k b)
+ Data.Map.NonEmpty.Lazy: traverseWithKey1 :: Apply t => (k -> a -> t b) -> NEMap k a -> t (NEMap k b)
+ Data.Map.NonEmpty.Lazy: union :: Ord k => NEMap k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unionMapLeft :: Ord k => Map k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unionMapRight :: Ord k => NEMap k a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unionMapWithKeyLeft :: Ord k => (k -> a -> a -> a) -> Map k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unionMapWithKeyRight :: Ord k => (k -> a -> a -> a) -> NEMap k a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unionMapWithLeft :: Ord k => (a -> a -> a) -> Map k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unionMapWithRight :: Ord k => (a -> a -> a) -> NEMap k a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unionWith :: Ord k => (a -> a -> a) -> NEMap k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unionWithKey :: Ord k => (k -> a -> a -> a) -> NEMap k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unions :: (Foldable1 f, Ord k) => f (NEMap k a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unionsWith :: (Foldable1 f, Ord k) => (a -> a -> a) -> f (NEMap k a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy: unsafeFromMap :: Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy: update :: Ord k => (a -> Maybe a) -> k -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: updateAt :: (k -> a -> Maybe a) -> Int -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> NEMap k a -> (Maybe a, Map k a)
+ Data.Map.NonEmpty.Lazy: updateMax :: (a -> Maybe a) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: updateMaxWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: updateMin :: (a -> Maybe a) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: updateMinWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy: valid :: Ord k => NEMap k a -> Bool
+ Data.Map.NonEmpty.Lazy: withNonEmpty :: r -> (NEMap k a -> r) -> Map k a -> r
+ Data.Map.NonEmpty.Lazy: withoutKeys :: Ord k => NEMap k a -> Set k -> Map k a
+ Data.Map.NonEmpty.Lazy.Internal: NEMap :: !k -> a -> !Map k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy.Internal: [nemK0] :: NEMap k a -> !k
+ Data.Map.NonEmpty.Lazy.Internal: [nemMap] :: NEMap k a -> !Map k a
+ Data.Map.NonEmpty.Lazy.Internal: [nemV0] :: NEMap k a -> a
+ Data.Map.NonEmpty.Lazy.Internal: data NEMap k a
+ Data.Map.NonEmpty.Lazy.Internal: elems :: NEMap k a -> NonEmpty a
+ Data.Map.NonEmpty.Lazy.Internal: foldMapWithKey :: Semigroup m => (k -> a -> m) -> NEMap k a -> m
+ Data.Map.NonEmpty.Lazy.Internal: foldl :: (a -> b -> a) -> a -> NEMap k b -> a
+ Data.Map.NonEmpty.Lazy.Internal: foldl' :: (a -> b -> a) -> a -> NEMap k b -> a
+ Data.Map.NonEmpty.Lazy.Internal: foldl1 :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Lazy.Internal: foldr :: (a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Lazy.Internal: foldr' :: (a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Lazy.Internal: foldr1 :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Lazy.Internal: fromList :: Ord k => NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy.Internal: insertMaxMap :: k -> a -> Map k a -> Map k a
+ Data.Map.NonEmpty.Lazy.Internal: insertMinMap :: k -> a -> Map k a -> Map k a
+ Data.Map.NonEmpty.Lazy.Internal: insertWith :: Ord k => (a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy.Internal: instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: instance (Data.Aeson.Types.FromJSON.FromJSONKey k, GHC.Classes.Ord k, Data.Aeson.Types.FromJSON.FromJSON a) => Data.Aeson.Types.FromJSON.FromJSON (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: instance (Data.Aeson.Types.ToJSON.ToJSONKey k, Data.Aeson.Types.ToJSON.ToJSON a) => Data.Aeson.Types.ToJSON.ToJSON (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: instance (Data.Data.Data k, Data.Data.Data a, GHC.Classes.Ord k) => Data.Data.Data (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: instance (GHC.Classes.Eq k, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: instance (GHC.Classes.Ord k, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: instance (GHC.Classes.Ord k, GHC.Read.Read k) => Data.Functor.Classes.Read1 (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance (GHC.Classes.Ord k, GHC.Read.Read k, GHC.Read.Read e) => GHC.Read.Read (Data.Map.NonEmpty.Lazy.Internal.NEMap k e)
+ Data.Map.NonEmpty.Lazy.Internal: instance (GHC.Show.Show k, GHC.Show.Show a) => GHC.Show.Show (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: instance Control.Comonad.Comonad (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance Data.Foldable.Foldable (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance Data.Foldable1.Foldable1 (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance Data.Functor.Classes.Eq2 Data.Map.NonEmpty.Lazy.Internal.NEMap
+ Data.Map.NonEmpty.Lazy.Internal: instance Data.Functor.Classes.Ord2 Data.Map.NonEmpty.Lazy.Internal.NEMap
+ Data.Map.NonEmpty.Lazy.Internal: instance Data.Functor.Classes.Show2 Data.Map.NonEmpty.Lazy.Internal.NEMap
+ Data.Map.NonEmpty.Lazy.Internal: instance Data.Functor.Invariant.Invariant (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance Data.Semigroup.Traversable.Class.Traversable1 (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance Data.Traversable.Traversable (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance GHC.Base.Functor (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance GHC.Classes.Eq k => Data.Functor.Classes.Eq1 (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance GHC.Classes.Ord k => Data.Functor.Alt.Alt (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance GHC.Classes.Ord k => Data.Functor.Classes.Ord1 (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance GHC.Classes.Ord k => GHC.Base.Semigroup (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: instance GHC.Classes.Ord k => GHC.IsList.IsList (Data.Map.NonEmpty.Lazy.Internal.NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: instance GHC.Show.Show k => Data.Functor.Classes.Show1 (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance WithIndex.FoldableWithIndex k (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance WithIndex.FunctorWithIndex k (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: instance WithIndex.TraversableWithIndex k (Data.Map.NonEmpty.Lazy.Internal.NEMap k)
+ Data.Map.NonEmpty.Lazy.Internal: map :: (a -> b) -> NEMap k a -> NEMap k b
+ Data.Map.NonEmpty.Lazy.Internal: nonEmptyMap :: Map k a -> Maybe (NEMap k a)
+ Data.Map.NonEmpty.Lazy.Internal: singleton :: k -> a -> NEMap k a
+ Data.Map.NonEmpty.Lazy.Internal: size :: NEMap k a -> Int
+ Data.Map.NonEmpty.Lazy.Internal: toList :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Lazy.Internal: toMap :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Lazy.Internal: traverseWithKey :: Applicative t => (k -> a -> t b) -> NEMap k a -> t (NEMap k b)
+ Data.Map.NonEmpty.Lazy.Internal: traverseWithKey1 :: Apply t => (k -> a -> t b) -> NEMap k a -> t (NEMap k b)
+ Data.Map.NonEmpty.Lazy.Internal: union :: Ord k => NEMap k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Lazy.Internal: unions :: (Foldable1 f, Ord k) => f (NEMap k a) -> NEMap k a
+ Data.Map.NonEmpty.Lazy.Internal: valid :: Ord k => NEMap k a -> Bool
+ Data.Map.NonEmpty.Lazy.Internal: withNonEmpty :: r -> (NEMap k a -> r) -> Map k a -> r
+ Data.Map.NonEmpty.Strict: (!) :: Ord k => NEMap k a -> k -> a
+ Data.Map.NonEmpty.Strict: (!?) :: Ord k => NEMap k a -> k -> Maybe a
+ Data.Map.NonEmpty.Strict: (\\) :: Ord k => NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Strict: absurdNEMap :: NEMap Void a -> b
+ Data.Map.NonEmpty.Strict: adjust :: Ord k => (a -> a) -> k -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: adjustAt :: (k -> a -> a) -> Int -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: adjustMax :: (a -> a) -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: adjustMaxWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: adjustMin :: (a -> a) -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: adjustMinWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: adjustWithKey :: Ord k => (k -> a -> a) -> k -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: alter :: Ord k => (Maybe a -> Maybe a) -> k -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: alter' :: Ord k => (Maybe a -> a) -> k -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: alterF :: (Ord k, Functor f) => (Maybe a -> f (Maybe a)) -> k -> NEMap k a -> f (Map k a)
+ Data.Map.NonEmpty.Strict: alterF' :: (Ord k, Functor f) => (Maybe a -> f a) -> k -> NEMap k a -> f (NEMap k a)
+ Data.Map.NonEmpty.Strict: assocs :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Strict: delete :: Ord k => k -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: deleteAt :: Int -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: deleteFindMax :: NEMap k a -> ((k, a), Map k a)
+ Data.Map.NonEmpty.Strict: deleteFindMin :: NEMap k a -> ((k, a), Map k a)
+ Data.Map.NonEmpty.Strict: deleteMax :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: deleteMaybe :: Ord k => k -> NEMap k a -> Maybe (NEMap k a)
+ Data.Map.NonEmpty.Strict: deleteMin :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: difference :: Ord k => NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Strict: differenceWith :: Ord k => (a -> b -> Maybe a) -> NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Strict: differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Strict: drop :: Int -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: dropWhileAntitone :: (k -> Bool) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: elemAt :: Int -> NEMap k a -> (k, a)
+ Data.Map.NonEmpty.Strict: elems :: NEMap k a -> NonEmpty a
+ Data.Map.NonEmpty.Strict: filter :: (a -> Bool) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: filterWithKey :: (k -> a -> Bool) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: findIndex :: Ord k => k -> NEMap k a -> Int
+ Data.Map.NonEmpty.Strict: findMax :: NEMap k a -> (k, a)
+ Data.Map.NonEmpty.Strict: findMin :: NEMap k a -> (k, a)
+ Data.Map.NonEmpty.Strict: findWithDefault :: Ord k => a -> k -> NEMap k a -> a
+ Data.Map.NonEmpty.Strict: foldMapWithKey :: Monoid m => (k -> a -> m) -> NEMap k a -> m
+ Data.Map.NonEmpty.Strict: foldl :: (b -> a -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict: foldl' :: (b -> a -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict: foldl1 :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Strict: foldl1' :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Strict: foldlWithKey :: (a -> k -> b -> a) -> a -> NEMap k b -> a
+ Data.Map.NonEmpty.Strict: foldlWithKey' :: (a -> k -> b -> a) -> a -> NEMap k b -> a
+ Data.Map.NonEmpty.Strict: foldr :: (a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict: foldr' :: (a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict: foldr1 :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Strict: foldr1' :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Strict: foldrWithKey :: (k -> a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict: foldrWithKey' :: (k -> a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict: fromAscList :: Eq k => NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromAscListWith :: Eq k => (a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromDescList :: Eq k => NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromDescListWith :: Eq k => (a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromDistinctAscList :: NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromDistinctDescList :: NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromList :: Ord k => NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromListWith :: Ord k => (a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromListWithKey :: Ord k => (k -> a -> a -> a) -> NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: fromSet :: (k -> a) -> NESet k -> NEMap k a
+ Data.Map.NonEmpty.Strict: infixl 9 !
+ Data.Map.NonEmpty.Strict: insert :: Ord k => k -> a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> NEMap k a -> (Maybe a, NEMap k a)
+ Data.Map.NonEmpty.Strict: insertMap :: Ord k => k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: insertMapMax :: k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: insertMapMin :: k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: insertMapWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: insertMapWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: insertWith :: Ord k => (a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: intersection :: Ord k => NEMap k a -> NEMap k b -> Map k a
+ Data.Map.NonEmpty.Strict: intersectionWith :: Ord k => (a -> b -> c) -> NEMap k a -> NEMap k b -> Map k c
+ Data.Map.NonEmpty.Strict: intersectionWithKey :: Ord k => (k -> a -> b -> c) -> NEMap k a -> NEMap k b -> Map k c
+ Data.Map.NonEmpty.Strict: isProperSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool
+ Data.Map.NonEmpty.Strict: isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> NEMap k a -> NEMap k b -> Bool
+ Data.Map.NonEmpty.Strict: isSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool
+ Data.Map.NonEmpty.Strict: isSubmapOfBy :: Ord k => (a -> b -> Bool) -> NEMap k a -> NEMap k b -> Bool
+ Data.Map.NonEmpty.Strict: keys :: NEMap k a -> NonEmpty k
+ Data.Map.NonEmpty.Strict: keysSet :: NEMap k a -> NESet k
+ Data.Map.NonEmpty.Strict: lookup :: Ord k => k -> NEMap k a -> Maybe a
+ Data.Map.NonEmpty.Strict: lookupGE :: Ord k => k -> NEMap k a -> Maybe (k, a)
+ Data.Map.NonEmpty.Strict: lookupGT :: Ord k => k -> NEMap k a -> Maybe (k, a)
+ Data.Map.NonEmpty.Strict: lookupIndex :: Ord k => k -> NEMap k a -> Maybe Int
+ Data.Map.NonEmpty.Strict: lookupLE :: Ord k => k -> NEMap k a -> Maybe (k, a)
+ Data.Map.NonEmpty.Strict: lookupLT :: Ord k => k -> NEMap k a -> Maybe (k, a)
+ Data.Map.NonEmpty.Strict: map :: (a -> b) -> NEMap k a -> NEMap k b
+ Data.Map.NonEmpty.Strict: mapAccum :: (a -> b -> (a, c)) -> a -> NEMap k b -> (a, NEMap k c)
+ Data.Map.NonEmpty.Strict: mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> NEMap k b -> (a, NEMap k c)
+ Data.Map.NonEmpty.Strict: mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> NEMap k b -> (a, NEMap k c)
+ Data.Map.NonEmpty.Strict: mapEither :: (a -> Either b c) -> NEMap k a -> These (NEMap k b) (NEMap k c)
+ Data.Map.NonEmpty.Strict: mapEitherWithKey :: (k -> a -> Either b c) -> NEMap k a -> These (NEMap k b) (NEMap k c)
+ Data.Map.NonEmpty.Strict: mapKeys :: Ord k2 => (k1 -> k2) -> NEMap k1 a -> NEMap k2 a
+ Data.Map.NonEmpty.Strict: mapKeysMonotonic :: (k1 -> k2) -> NEMap k1 a -> NEMap k2 a
+ Data.Map.NonEmpty.Strict: mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> NEMap k1 a -> NEMap k2 a
+ Data.Map.NonEmpty.Strict: mapMaybe :: (a -> Maybe b) -> NEMap k a -> Map k b
+ Data.Map.NonEmpty.Strict: mapMaybeWithKey :: (k -> a -> Maybe b) -> NEMap k a -> Map k b
+ Data.Map.NonEmpty.Strict: mapWithKey :: (k -> a -> b) -> NEMap k a -> NEMap k b
+ Data.Map.NonEmpty.Strict: maxView :: NEMap k a -> (a, Map k a)
+ Data.Map.NonEmpty.Strict: member :: Ord k => k -> NEMap k a -> Bool
+ Data.Map.NonEmpty.Strict: minView :: NEMap k a -> (a, Map k a)
+ Data.Map.NonEmpty.Strict: nonEmptyMap :: Map k a -> Maybe (NEMap k a)
+ Data.Map.NonEmpty.Strict: notMember :: Ord k => k -> NEMap k a -> Bool
+ Data.Map.NonEmpty.Strict: partition :: (a -> Bool) -> NEMap k a -> These (NEMap k a) (NEMap k a)
+ Data.Map.NonEmpty.Strict: partitionWithKey :: (k -> a -> Bool) -> NEMap k a -> These (NEMap k a) (NEMap k a)
+ Data.Map.NonEmpty.Strict: pattern IsEmpty :: Map k a
+ Data.Map.NonEmpty.Strict: pattern IsNonEmpty :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: restrictKeys :: Ord k => NEMap k a -> Set k -> Map k a
+ Data.Map.NonEmpty.Strict: singleton :: k -> a -> NEMap k a
+ Data.Map.NonEmpty.Strict: size :: NEMap k a -> Int
+ Data.Map.NonEmpty.Strict: spanAntitone :: (k -> Bool) -> NEMap k a -> These (NEMap k a) (NEMap k a)
+ Data.Map.NonEmpty.Strict: split :: Ord k => k -> NEMap k a -> Maybe (These (NEMap k a) (NEMap k a))
+ Data.Map.NonEmpty.Strict: splitAt :: Int -> NEMap k a -> These (NEMap k a) (NEMap k a)
+ Data.Map.NonEmpty.Strict: splitLookup :: Ord k => k -> NEMap k a -> These a (These (NEMap k a) (NEMap k a))
+ Data.Map.NonEmpty.Strict: splitRoot :: NEMap k a -> NonEmpty (NEMap k a)
+ Data.Map.NonEmpty.Strict: take :: Int -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: takeWhileAntitone :: (k -> Bool) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: toAscList :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Strict: toDescList :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Strict: toList :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Strict: toMap :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: traverseMaybeWithKey :: Applicative t => (k -> a -> t (Maybe b)) -> NEMap k a -> t (Map k b)
+ Data.Map.NonEmpty.Strict: traverseMaybeWithKey1 :: Apply t => (k -> a -> t (Maybe b)) -> NEMap k a -> t (Map k b)
+ Data.Map.NonEmpty.Strict: traverseWithKey :: Applicative f => (k -> a -> f b) -> NEMap k a -> f (NEMap k b)
+ Data.Map.NonEmpty.Strict: traverseWithKey1 :: Apply f => (k -> a -> f b) -> NEMap k a -> f (NEMap k b)
+ Data.Map.NonEmpty.Strict: type NEMap = NEMap
+ Data.Map.NonEmpty.Strict: union :: Ord k => NEMap k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: unionMapLeft :: Ord k => Map k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: unionMapRight :: Ord k => NEMap k a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: unionMapWithKeyLeft :: Ord k => (k -> a -> a -> a) -> Map k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: unionMapWithKeyRight :: Ord k => (k -> a -> a -> a) -> NEMap k a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: unionMapWithLeft :: Ord k => (a -> a -> a) -> Map k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: unionMapWithRight :: Ord k => (a -> a -> a) -> NEMap k a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: unionWith :: Ord k => (a -> a -> a) -> NEMap k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: unionWithKey :: Ord k => (k -> a -> a -> a) -> NEMap k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: unions :: (Foldable1 f, Ord k) => f (NEMap k a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: unionsWith :: (Foldable1 f, Ord k) => (a -> a -> a) -> f (NEMap k a) -> NEMap k a
+ Data.Map.NonEmpty.Strict: unsafeFromMap :: Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict: update :: Ord k => (a -> Maybe a) -> k -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: updateAt :: (k -> a -> Maybe a) -> Int -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> NEMap k a -> (Maybe a, Map k a)
+ Data.Map.NonEmpty.Strict: updateMax :: (a -> Maybe a) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: updateMaxWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: updateMin :: (a -> Maybe a) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: updateMinWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict: valid :: Ord k => NEMap k a -> Bool
+ Data.Map.NonEmpty.Strict: withNonEmpty :: b -> (NEMap k a -> b) -> Map k a -> b
+ Data.Map.NonEmpty.Strict: withoutKeys :: Ord k => NEMap k a -> Set k -> Map k a
+ Data.Map.NonEmpty.Strict.Internal: elems :: NEMap k a -> NonEmpty a
+ Data.Map.NonEmpty.Strict.Internal: foldMapWithKey :: Monoid m => (k -> a -> m) -> NEMap k a -> m
+ Data.Map.NonEmpty.Strict.Internal: foldl :: (b -> a -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict.Internal: foldl' :: (b -> a -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict.Internal: foldl1 :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Strict.Internal: foldr :: (a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict.Internal: foldr' :: (a -> b -> b) -> b -> NEMap k a -> b
+ Data.Map.NonEmpty.Strict.Internal: foldr1 :: (a -> a -> a) -> NEMap k a -> a
+ Data.Map.NonEmpty.Strict.Internal: fromList :: Ord k => NonEmpty (k, a) -> NEMap k a
+ Data.Map.NonEmpty.Strict.Internal: insertMaxMap :: k -> a -> Map k a -> Map k a
+ Data.Map.NonEmpty.Strict.Internal: insertMinMap :: k -> a -> Map k a -> Map k a
+ Data.Map.NonEmpty.Strict.Internal: insertWith :: Ord k => (a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict.Internal: map :: (a -> b) -> NEMap k a -> NEMap k b
+ Data.Map.NonEmpty.Strict.Internal: nemMap :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict.Internal: nonEmptyMap :: Map k a -> Maybe (NEMap k a)
+ Data.Map.NonEmpty.Strict.Internal: pattern NEMap :: k -> a -> Map k a -> NEMap k a
+ Data.Map.NonEmpty.Strict.Internal: singleton :: k -> a -> NEMap k a
+ Data.Map.NonEmpty.Strict.Internal: size :: NEMap k a -> Int
+ Data.Map.NonEmpty.Strict.Internal: toList :: NEMap k a -> NonEmpty (k, a)
+ Data.Map.NonEmpty.Strict.Internal: toMap :: NEMap k a -> Map k a
+ Data.Map.NonEmpty.Strict.Internal: traverseWithKey :: Applicative f => (k -> a -> f b) -> NEMap k a -> f (NEMap k b)
+ Data.Map.NonEmpty.Strict.Internal: traverseWithKey1 :: Apply f => (k -> a -> f b) -> NEMap k a -> f (NEMap k b)
+ Data.Map.NonEmpty.Strict.Internal: type NEMap = NEMap
+ Data.Map.NonEmpty.Strict.Internal: union :: Ord k => NEMap k a -> NEMap k a -> NEMap k a
+ Data.Map.NonEmpty.Strict.Internal: unions :: (Foldable1 f, Ord k) => f (NEMap k a) -> NEMap k a
+ Data.Map.NonEmpty.Strict.Internal: valid :: Ord k => NEMap k a -> Bool
+ Data.Map.NonEmpty.Strict.Internal: withNonEmpty :: b -> (NEMap k a -> b) -> Map k a -> b
Files
- CHANGELOG.md +13/−0
- nonempty-containers.cabal +11/−1
- src/Data/IntMap/NonEmpty.hs +18/−2075
- src/Data/IntMap/NonEmpty/Internal.hs +5/−725
- src/Data/IntMap/NonEmpty/Lazy.hs +2072/−0
- src/Data/IntMap/NonEmpty/Lazy/Internal.hs +739/−0
- src/Data/IntMap/NonEmpty/Strict.hs +2072/−0
- src/Data/IntMap/NonEmpty/Strict/Internal.hs +186/−0
- src/Data/Map/NonEmpty.hs +18/−2495
- src/Data/Map/NonEmpty/Internal.hs +4/−712
- src/Data/Map/NonEmpty/Lazy.hs +2492/−0
- src/Data/Map/NonEmpty/Lazy/Internal.hs +726/−0
- src/Data/Map/NonEmpty/Strict.hs +2492/−0
- src/Data/Map/NonEmpty/Strict/Internal.hs +193/−0
- test/Spec.hs +4/−0
- test/Tests/IntMap.hs +17/−0
- test/Tests/IntMap/Strict.hs +1208/−0
- test/Tests/Map.hs +17/−0
- test/Tests/Map/Strict.hs +1338/−0
- test/Tests/Util.hs +20/−0
CHANGELOG.md view
@@ -1,6 +1,19 @@ Changelog ========= +Version 0.4.0.0+---------------++*September 27, 2026*++<https://github.com/mstksg/nonempty-containers/releases/tag/v0.4.0.0>++* Add `Data.Map.NonEmpty.Lazy`, `Data.Map.NonEmpty.Strict`,+ `Data.IntMap.NonEmpty.Lazy`, and `Data.IntMap.NonEmpty.Strict`.+ The existing `Data.Map.NonEmpty` and `Data.IntMap.NonEmpty` modules+ continue to re-export the lazy interfaces so the imports should be+ backwards-compatible.+ Version 0.3.6.0 ---------------
nonempty-containers.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: nonempty-containers-version: 0.3.6.0+version: 0.4.0.0 synopsis: Non-empty variants of containers data types, with full API description: Efficient and optimized non-empty versions of types from /containers/.@@ -39,10 +39,18 @@ Data.Containers.NonEmpty.List Data.IntMap.NonEmpty Data.IntMap.NonEmpty.Internal+ Data.IntMap.NonEmpty.Lazy+ Data.IntMap.NonEmpty.Lazy.Internal+ Data.IntMap.NonEmpty.Strict+ Data.IntMap.NonEmpty.Strict.Internal Data.IntSet.NonEmpty Data.IntSet.NonEmpty.Internal Data.Map.NonEmpty Data.Map.NonEmpty.Internal+ Data.Map.NonEmpty.Lazy+ Data.Map.NonEmpty.Lazy.Internal+ Data.Map.NonEmpty.Strict+ Data.Map.NonEmpty.Strict.Internal Data.Sequence.NonEmpty Data.Sequence.NonEmpty.Internal Data.Set.NonEmpty@@ -72,8 +80,10 @@ other-modules: Paths_nonempty_containers Tests.IntMap+ Tests.IntMap.Strict Tests.IntSet Tests.Map+ Tests.Map.Strict Tests.NonEmptyList Tests.Sequence Tests.Set
src/Data/IntMap/NonEmpty.hs view
@@ -1,2075 +1,18 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE ViewPatterns #-}---- |--- Module : Data.IntMap.NonEmpty--- Copyright : (c) Justin Le 2018--- License : BSD3------ Maintainer : justin@jle.im--- Stability : experimental--- Portability : non-portable------ = Non-Empty Finite Integer-Indexed Maps (lazy interface)------ The @'NEIntMap' v@ type represents a non-empty finite map (sometimes--- called a dictionary) from integer keys to values of type @v@.--- An 'NEIntMap' is strict in its keys but lazy in its values.------ See documentation for 'NEIntMap' for information on how to convert and--- manipulate such non-empty maps.------ This module essentially re-imports the API of "Data.IntMap.Lazy" and its--- 'IntMap' type, along with semantics and asymptotics. In most--- situations, asymptotics are different only by a constant factor. In--- some situations, asmyptotics are even better (constant-time instead of--- log-time).------ Because 'NEIntMap' is implemented using 'IntMap', all of the caveats of using--- 'IntMap' apply (such as the limitation of the maximum size of maps).------ All functions take non-empty maps as inputs. In situations where their--- results can be guarunteed to also be non-empty, they also return--- non-empty maps. In situations where their results could potentially be--- empty, 'IntMap' is returned instead.------ Some variants of functions (like 'alter'', 'alterF'', 'adjustMin',--- 'adjustMax', 'adjustMinWithKey', 'adjustMaxWithKey') are provided in--- a way restructured to preserve guaruntees of non-empty maps being--- returned.------ Some functions (like 'mapEither', 'partition', 'split')--- have modified return types to account for possible configurations of--- non-emptiness.------ This module is intended to be imported qualified, to avoid name clashes with--- "Prelude" and "Data.IntMap" functions:------ > import qualified Data.IntMap.NonEmpty as NEIM------ Note that all asmyptotics /O(f(n))/ in this module are actually--- /O(min(W, f(n)))/, where @W@ is the number of bits in an 'Int' (32 or--- 64). That is, if @f(n)@ is greater than @W@, all operations are--- constant-time.------ At the moment, this package does not provide a variant strict on values--- for these functions, like /containers/ does. This is a planned future--- implementation (PR's are appreciated). For now, you can simulate--- a strict interface by manually forcing values before returning results.-module Data.IntMap.NonEmpty (- -- * Non-Empty IntMap Type- NEIntMap,- Key,-- -- ** Conversions between empty and non-empty maps- pattern IsNonEmpty,- pattern IsEmpty,- nonEmptyMap,- toMap,- withNonEmpty,- insertMap,- insertMapWith,- insertMapWithKey,- insertMapMin,- insertMapMax,- unsafeFromMap,-- -- * Construction- singleton,- fromSet,-- -- ** From Unordered Lists- fromList,- fromListWith,- fromListWithKey,-- -- ** From Ascending Lists- fromAscList,- fromAscListWith,- fromAscListWithKey,- fromDistinctAscList,-- -- * Insertion- insert,- insertWith,- insertWithKey,- insertLookupWithKey,-- -- * Deletion\/Update- delete,- deleteMaybe,- adjust,- adjustWithKey,- update,- updateWithKey,- updateLookupWithKey,- alter,- alterF,- alter',- alterF',-- -- * Query-- -- ** Lookup- lookup,- (!?),- (!),- findWithDefault,- member,- notMember,- lookupLT,- lookupGT,- lookupLE,- lookupGE,-- -- ** Size- size,-- -- * Combine-- -- ** Union- union,- unionMapLeft,- unionMapRight,- unionWith,- unionMapWithLeft,- unionMapWithRight,- unionWithKey,- unionMapWithKeyLeft,- unionMapWithKeyRight,- unions,- unionsWith,-- -- ** Difference- difference,- (\\),- differenceWith,- differenceWithKey,-- -- ** Intersection- intersection,- intersectionWith,- intersectionWithKey,- -- -- ** Universal combining function- -- , mergeWithKey-- -- * Traversal-- -- ** Map- map,- mapWithKey,- traverseWithKey1,- traverseWithKey,- mapAccum,- mapAccumWithKey,- mapAccumRWithKey,- mapKeys,- mapKeysWith,- mapKeysMonotonic,-- -- * Folds- foldr,- foldl,- foldr1,- foldl1,- foldrWithKey,- foldlWithKey,- foldMapWithKey,-- -- ** Strict folds- foldr',- foldr1',- foldl',- foldl1',- foldrWithKey',- foldlWithKey',-- -- * Conversion- elems,- keys,- assocs,- keysSet,-- -- ** Lists- toList,-- -- ** Ordered lists- toAscList,- toDescList,-- -- * Filter- filter,- filterWithKey,- restrictKeys,- withoutKeys,- partition,- partitionWithKey,- mapMaybe,- mapMaybeWithKey,- mapEither,- mapEitherWithKey,- split,- splitLookup,- splitRoot,-- -- * Submap- isSubmapOf,- isSubmapOfBy,- isProperSubmapOf,- isProperSubmapOfBy,-- -- * Min\/Max- findMin,- findMax,- deleteMin,- deleteMax,- deleteFindMin,- deleteFindMax,- updateMin,- updateMax,- adjustMin,- adjustMax,- updateMinWithKey,- updateMaxWithKey,- adjustMinWithKey,- adjustMaxWithKey,- minView,- maxView,-- -- * Debugging- valid,-) where--import Control.Applicative-import Data.Bifunctor-import qualified Data.Foldable as F-import Data.Functor.Identity-import qualified Data.IntMap as M-import Data.IntMap.Internal (IntMap (..))-import Data.IntMap.NonEmpty.Internal-import Data.IntSet (IntSet)-import qualified Data.IntSet as S-import Data.IntSet.NonEmpty.Internal (NEIntSet (..))-import Data.List.NonEmpty (NonEmpty (..))-import qualified Data.List.NonEmpty as NE-import Data.Maybe hiding (mapMaybe)-import qualified Data.Maybe as Maybe-import Data.Semigroup.Foldable (Foldable1)-import qualified Data.Semigroup.Foldable as F1-import Data.These-import Prelude hiding (Foldable (..), filter, lookup, map)---- | /O(1)/ match, /O(log n)/ usage of contents. The 'IsNonEmpty' and--- 'IsEmpty' patterns allow you to treat a 'IntMap' as if it were either--- a @'IsNonEmpty' n@ (where @n@ is a 'NEIntMap') or an 'IsEmpty'.------ For example, you can pattern match on a 'IntMap':------ @--- myFunc :: 'IntMap' K X -> Y--- myFunc ('IsNonEmpty' n) = -- here, the user provided a non-empty map, and @n@ is the 'NEIntMap'--- myFunc 'IsEmpty' = -- here, the user provided an empty map.--- @------ Matching on @'IsNonEmpty' n@ means that the original 'IntMap' was /not/--- empty, and you have a verified-non-empty 'NEIntMap' @n@ to use.------ Note that patching on this pattern is /O(1)/. However, using the--- contents requires a /O(log n)/ cost that is deferred until after the--- pattern is matched on (and is not incurred at all if the contents are--- never used).------ A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides--- complete coverage.------ This is a bidirectional pattern, so you can use 'IsNonEmpty' to convert--- a 'NEIntMap' back into a 'IntMap', obscuring its non-emptiness (see 'toMap').-pattern IsNonEmpty :: NEIntMap a -> IntMap a-pattern IsNonEmpty n <- (nonEmptyMap -> Just n)- where- IsNonEmpty n = toMap n---- | /O(1)/. The 'IsNonEmpty' and 'IsEmpty' patterns allow you to treat--- a 'IntMap' as if it were either a @'IsNonEmpty' n@ (where @n@ is--- a 'NEIntMap') or an 'IsEmpty'.------ Matching on 'IsEmpty' means that the original 'IntMap' was empty.------ A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides--- complete coverage.------ This is a bidirectional pattern, so you can use 'IsEmpty' as an--- expression, and it will be interpreted as 'Data.IntMap.empty'.------ See 'IsNonEmpty' for more information.-pattern IsEmpty :: IntMap a-pattern IsEmpty <- (M.null -> True)- where- IsEmpty = M.empty--{-# COMPLETE IsNonEmpty, IsEmpty #-}---- | /O(log n)/. Unsafe version of 'nonEmptyMap'. Coerces a 'IntMap' into an--- 'NEIntMap', but is undefined (throws a runtime exception when evaluation is--- attempted) for an empty 'IntMap'.-unsafeFromMap ::- IntMap a ->- NEIntMap a-unsafeFromMap = withNonEmpty e id- where- e = errorWithoutStackTrace "NEIntMap.unsafeFromMap: empty map"-{-# INLINE unsafeFromMap #-}---- | /O(log n)/. Convert a 'IntMap' into an 'NEIntMap' by adding a key-value--- pair. Because of this, we know that the map must have at least one--- element, and so therefore cannot be empty. If key is already present,--- will overwrite the original value.------ See 'insertMapMin' for a version that is constant-time if the new key is--- /strictly smaller than/ all keys in the original map.------ > insertMap 4 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])--- > insertMap 4 "c" Data.IntMap.empty == singleton 4 "c"-insertMap :: Key -> a -> IntMap a -> NEIntMap a-insertMap k v = withNonEmpty (singleton k v) (insert k v)-{-# INLINE insertMap #-}---- | /O(log n)/. Convert a 'IntMap' into an 'NEIntMap' by adding a key-value--- pair. Because of this, we know that the map must have at least one--- element, and so therefore cannot be empty. Uses a combining function--- with the new value as the first argument if the key is already present.------ > insertMapWith (++) 4 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])--- > insertMapWith (++) 5 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"ca")])-insertMapWith ::- (a -> a -> a) ->- Key ->- a ->- IntMap a ->- NEIntMap a-insertMapWith f k v = withNonEmpty (singleton k v) (insertWith f k v)-{-# INLINE insertMapWith #-}---- | /O(log n)/. Convert a 'IntMap' into an 'NEIntMap' by adding a key-value--- pair. Because of this, we know that the map must have at least one--- element, and so therefore cannot be empty. Uses a combining function--- with the key and new value as the first and second arguments if the key--- is already present.------ > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value--- > insertWithKey f 5 "xxx" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "5:xxx|a")])--- > insertWithKey f 7 "xxx" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])--- > insertWithKey f 5 "xxx" Data.IntMap.empty == singleton 5 "xxx"-insertMapWithKey ::- (Key -> a -> a -> a) ->- Key ->- a ->- IntMap a ->- NEIntMap a-insertMapWithKey f k v = withNonEmpty (singleton k v) (insertWithKey f k v)-{-# INLINE insertMapWithKey #-}---- | /O(1)/ Convert a 'IntMap' into an 'NEIntMap' by adding a key-value pair--- where the key is /strictly less than/ all keys in the input map. The--- keys in the original map must all be /strictly greater than/ the new--- key. /The precondition is not checked./------ > insertMapMin 2 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((2,"c") :| [(3,"b"), (5,"a")])--- > valid (insertMapMin 2 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == True--- > valid (insertMapMin 7 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False--- > valid (insertMapMin 3 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False-insertMapMin ::- Key ->- a ->- IntMap a ->- NEIntMap a-insertMapMin = NEIntMap-{-# INLINE insertMapMin #-}---- | /O(log n)/ Convert a 'IntMap' into an 'NEIntMap' by adding a key-value pair--- where the key is /strictly greater than/ all keys in the input map. The--- keys in the original map must all be /strictly less than/ the new--- key. /The precondition is not checked./------ At the current moment, this is identical simply 'insertMap'; however,--- it is left both for consistency and as a placeholder for a future--- version where optimizations are implemented to allow for a faster--- implementation.------ > insertMap 7 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"a"), (7,"c")])---- these currently are all valid, but shouldn't be--- > valid (insertMap 7 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == True--- > valid (insertMap 2 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False--- > valid (insertMap 5 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False-insertMapMax ::- Key ->- a ->- IntMap a ->- NEIntMap a-insertMapMax k v = withNonEmpty (singleton k v) go- where- go (NEIntMap k0 v0 m0) = NEIntMap k0 v0 . insertMaxMap k v $ m0-{-# INLINE insertMapMax #-}---- | /O(n)/. Build a non-empty map from a non-empty set of keys and--- a function which for each key computes its value.------ > fromSet (\k -> replicate k 'a') (Data.Set.NonEmpty.fromList (3 :| [5])) == fromList ((5,"aaaaa") :| [(3,"aaa")])-fromSet ::- (Key -> a) ->- NEIntSet ->- NEIntMap a-fromSet f (NEIntSet k ks) = NEIntMap k (f k) (M.fromSet f ks)-{-# INLINE fromSet #-}---- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs--- with a combining function. See also 'fromAscListWith'.------ > fromListWith (++) ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "ab") :| [(5, "aba")])-fromListWith ::- (a -> a -> a) ->- NonEmpty (Key, a) ->- NEIntMap a-fromListWith f = fromListWithKey (const f)-{-# INLINE fromListWith #-}---- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs--- with a combining function. See also 'fromAscListWithKey'.------ > let f k a1 a2 = (show k) ++ a1 ++ a2--- > fromListWithKey f ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "3ab") :| [(5, "5a5ba")])-fromListWithKey ::- (Key -> a -> a -> a) ->- NonEmpty (Key, a) ->- NEIntMap a-fromListWithKey f ((k0, v0) :| xs) = F.foldl' go (singleton k0 v0) xs- where- go m (k, v) = insertWithKey f k v m- {-# INLINE go #-}-{-# INLINE fromListWithKey #-}---- | /O(n)/. Build a map from an ascending non-empty list in linear time.--- /The precondition (input list is ascending) is not checked./------ > fromAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])--- > fromAscList ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "b")])--- > valid (fromAscList ((3,"b") :| [(5,"a"), (5,"b")])) == True--- > valid (fromAscList ((5,"a") :| [(3,"b"), (5,"b")])) == False-fromAscList ::- NonEmpty (Key, a) ->- NEIntMap a-fromAscList = fromDistinctAscList . combineEq-{-# INLINE fromAscList #-}---- | /O(n)/. Build a map from an ascending non-empty list in linear time--- with a combining function for equal keys. /The precondition (input list--- is ascending) is not checked./------ > fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "ba")])--- > valid (fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b"))]) == True--- > valid (fromAscListWith (++) ((5,"a") :| [(3,"b"), (5,"b"))]) == False-fromAscListWith ::- (a -> a -> a) ->- NonEmpty (Key, a) ->- NEIntMap a-fromAscListWith f = fromAscListWithKey (const f)-{-# INLINE fromAscListWith #-}---- | /O(n)/. Build a map from an ascending non-empty list in linear time--- with a combining function for equal keys. /The precondition (input list--- is ascending) is not checked./------ > let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2--- > fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")]) == fromList ((3, "b") :| [(5, "5:b5:ba")])--- > valid (fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")])) == True--- > valid (fromAscListWithKey f ((5,"a") :| [(3,"b"), (5,"b"), (5,"b")])) == False-fromAscListWithKey ::- (Key -> a -> a -> a) ->- NonEmpty (Key, a) ->- NEIntMap a-fromAscListWithKey f = fromDistinctAscList . combineEqWith f-{-# INLINE fromAscListWithKey #-}---- | /O(n)/. Build a map from an ascending non-empty list of distinct--- elements in linear time. /The precondition is not checked./------ > fromDistinctAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])--- > valid (fromDistinctAscList ((3,"b") :| [(5,"a")])) == True--- > valid (fromDistinctAscList ((3,"b") :| [(5,"a"), (5,"b")])) == False-fromDistinctAscList :: NonEmpty (Key, a) -> NEIntMap a-fromDistinctAscList ((k, v) :| xs) =- insertMapMin k v- . M.fromDistinctAscList- $ xs-{-# INLINE fromDistinctAscList #-}---- | /O(log n)/. Insert a new key and value in the map.--- If the key is already present in the map, the associated value is--- replaced with the supplied value. 'insert' is equivalent to--- @'insertWith' 'const'@.------ See 'insertMap' for a version where the first argument is a 'IntMap'.------ > insert 5 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'x')])--- > insert 7 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'a'), (7, 'x')])-insert ::- Key ->- a ->- NEIntMap a ->- NEIntMap a-insert k v n@(NEIntMap k0 v0 m) = case compare k k0 of- LT -> NEIntMap k v . toMap $ n- EQ -> NEIntMap k v m- GT -> NEIntMap k0 v0 . M.insert k v $ m-{-# INLINE insert #-}---- | /O(log n)/. Insert with a function, combining key, new value and old--- value. @'insertWithKey' f key value mp@ will insert the pair (key,--- value) into @mp@ if key does not exist in the map. If the key does--- exist, the function will insert the pair @(key,f key new_value--- old_value)@. Note that the key passed to f is the same key passed to--- 'insertWithKey'.------ See 'insertMapWithKey' for a version where the first argument is a 'IntMap'.------ > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value--- > insertWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:xxx|a")])--- > insertWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])-insertWithKey ::- (Key -> a -> a -> a) ->- Key ->- a ->- NEIntMap a ->- NEIntMap a-insertWithKey f k v n@(NEIntMap k0 v0 m) = case compare k k0 of- LT -> NEIntMap k v . toMap $ n- EQ -> NEIntMap k (f k v v0) m- GT -> NEIntMap k0 v0 $ M.insertWithKey f k v m-{-# INLINE insertWithKey #-}---- | /O(log n)/. Combines insert operation with old value retrieval. The--- expression (@'insertLookupWithKey' f k x map@) is a pair where the first--- element is equal to (@'lookup' k map@) and the second element equal to--- (@'insertWithKey' f k x map@).------ > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value--- > insertLookupWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "5:xxx|a")]))--- > insertLookupWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "xxx")]))------ This is how to define @insertLookup@ using @insertLookupWithKey@:------ > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t--- > insertLookup 5 "x" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "x")]))--- > insertLookup 7 "x" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "x")]))-insertLookupWithKey ::- (Key -> a -> a -> a) ->- Key ->- a ->- NEIntMap a ->- (Maybe a, NEIntMap a)-insertLookupWithKey f k v n@(NEIntMap k0 v0 m) = case compare k k0 of- LT -> (Nothing, NEIntMap k v . toMap $ n)- EQ -> (Just v, NEIntMap k (f k v v0) m)- GT -> NEIntMap k0 v0 <$> M.insertLookupWithKey f k v m-{-# INLINE insertLookupWithKey #-}---- | /O(log n)/. Delete a key and its value from the non-empty map.--- A potentially empty map ('IntMap') is returned, since this might delete the--- last item in the 'NEIntMap'. When the key is not a member of the map, is--- equivalent to 'toMap'.------ > delete 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"--- > delete 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.Singleton [(3, "b"), (5, "a")]-delete :: Key -> NEIntMap a -> IntMap a-delete k n@(NEIntMap k0 v m) = case compare k k0 of- LT -> toMap n- EQ -> m- GT -> insertMinMap k0 v . M.delete k $ m-{-# INLINE delete #-}---- | /O(log n)/. Delete a key and its value from the non-empty map, returning--- 'Nothing' if the result would be empty.------ This is more efficient than @'nonEmptyMap' . 'delete' k@ because it avoids--- converting the known-minimum representation back through 'IntMap' when the--- deleted key is not the minimum.------ @since 0.3.6.0-deleteMaybe :: Key -> NEIntMap a -> Maybe (NEIntMap a)-deleteMaybe k n@(NEIntMap k0 v m) = case compare k k0 of- LT -> Just n- EQ -> nonEmptyMap m- GT -> Just . NEIntMap k0 v . M.delete k $ m-{-# INLINE deleteMaybe #-}---- | /O(log n)/. Update a value at a specific key with the result of the--- provided function. When the key is not a member of the map, the original--- map is returned.------ > adjust ("new " ++) 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "new a")])--- > adjust ("new " ++) 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])-adjust ::- (a -> a) ->- Key ->- NEIntMap a ->- NEIntMap a-adjust f = adjustWithKey (const f)-{-# INLINE adjust #-}---- | /O(log n)/. Adjust a value at a specific key. When the key is not--- a member of the map, the original map is returned.------ > let f key x = (show key) ++ ":new " ++ x--- > adjustWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:new a")])--- > adjustWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])-adjustWithKey ::- (Key -> a -> a) ->- Key ->- NEIntMap a ->- NEIntMap a-adjustWithKey f k n@(NEIntMap k0 v m) = case compare k k0 of- LT -> n- EQ -> NEIntMap k0 (f k0 v) m- GT -> NEIntMap k0 v . M.adjustWithKey f k $ m-{-# INLINE adjustWithKey #-}---- | /O(log n)/. The expression (@'update' f k map@) updates the value @x@--- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is--- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.------ Returns a potentially empty map ('IntMap'), because we can't know ahead of--- time if the function returns 'Nothing' and deletes the final item in the--- 'NEIntMap'.------ > let f x = if x == "a" then Just "new a" else Nothing--- > update f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "new a")]--- > update f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a")]--- > update f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"-update ::- (a -> Maybe a) ->- Key ->- NEIntMap a ->- IntMap a-update f = updateWithKey (const f)-{-# INLINE update #-}---- | /O(log n)/. The expression (@'updateWithKey' f k map@) updates the--- value @x@ at @k@ (if it is in the map). If (@f k x@) is 'Nothing',--- the element is deleted. If it is (@'Just' y@), the key @k@ is bound--- to the new value @y@.------ Returns a potentially empty map ('IntMap'), because we can't know ahead of--- time if the function returns 'Nothing' and deletes the final item in the--- 'NEIntMap'.------ > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing--- > updateWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "5:new a")]--- > updateWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a")]--- > updateWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"-updateWithKey ::- (Key -> a -> Maybe a) ->- Key ->- NEIntMap a ->- IntMap a-updateWithKey f k n@(NEIntMap k0 v m) = case compare k k0 of- LT -> toMap n- EQ -> maybe m (flip (insertMinMap k0) m) . f k0 $ v- GT -> insertMinMap k0 v . M.updateWithKey f k $ m-{-# INLINE updateWithKey #-}---- | /O(min(n,W))/. Lookup and update.--- The function returns original value, if it is updated.--- This is different behavior than @Data.Map.NonEmpty.updateLookupWithKey@.--- Returns the original key value if the map entry is deleted.------ Returns a potentially empty map ('IntMap') in the case that we delete--- the final key of a singleton map.------ > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing--- > updateLookupWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == (Just "5:new a", Data.IntMap.fromList ((3, "b") :| [(5, "5:new a")]))--- > updateLookupWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == (Nothing, Data.IntMap.fromList ((3, "b") :| [(5, "a")]))--- > updateLookupWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == (Just "b", Data.IntMap.singleton 5 "a")-updateLookupWithKey ::- (Key -> a -> Maybe a) ->- Key ->- NEIntMap a ->- (Maybe a, IntMap a)-updateLookupWithKey f k n@(NEIntMap k0 v m) = case compare k k0 of- LT -> (Nothing, toMap n)- EQ ->- let u = f k0 v- in (Just v, maybe m (flip (insertMinMap k0) m) u)- GT -> fmap (insertMinMap k0 v) . M.updateLookupWithKey f k $ m-{-# INLINE updateLookupWithKey #-}---- | /O(log n)/. The expression (@'alter' f k map@) alters the value @x@ at--- @k@, or absence thereof. 'alter' can be used to insert, delete, or--- update a value in a 'IntMap'. In short : @Data.IntMap.lookup k ('alter'--- f k m) = f ('lookup' k m)@.------ Returns a potentially empty map ('IntMap'), because we can't know ahead of--- time if the function returns 'Nothing' and deletes the final item in the--- 'NEIntMap'.------ See 'alterF'' for a version that disallows deletion, and so therefore--- can return 'NEIntMap'.------ > let f _ = Nothing--- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a")]--- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"--- >--- > let f _ = Just "c"--- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a"), (7, "c")]--- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "c")]-alter ::- (Maybe a -> Maybe a) ->- Key ->- NEIntMap a ->- IntMap a-alter f k n@(NEIntMap k0 v m) = case compare k k0 of- LT -> maybe id (insertMinMap k) (f Nothing) (toMap n)- EQ -> maybe id (insertMinMap k0) (f (Just v)) m- GT -> insertMinMap k0 v . M.alter f k $ m-{-# INLINE alter #-}---- | /O(log n)/. The expression (@'alterF' f k map@) alters the value @x@--- at @k@, or absence thereof. 'alterF' can be used to inspect, insert,--- delete, or update a value in a 'IntMap'. In short: @Data.IntMap.lookup--- k \<$\> 'alterF' f k m = f ('lookup' k m)@.------ Example:------ @--- interactiveAlter :: Int -> NEIntMap Int String -> IO (IntMap Int String)--- interactiveAlter k m = alterF f k m where--- f Nothing = do--- putStrLn $ show k ++--- " was not found in the map. Would you like to add it?"--- getUserResponse1 :: IO (Maybe String)--- f (Just old) = do--- putStrLn $ "The key is currently bound to " ++ show old ++--- ". Would you like to change or delete it?"--- getUserResponse2 :: IO (Maybe String)--- @------ Like @Data.IntMap.alterF@ for 'IntMap', 'alterF' can be considered--- to be a unifying generalization of 'lookup' and 'delete'; however, as--- a constrast, it cannot be used to implement 'insert', because it must--- return a 'IntMap' instead of an 'NEIntMap' (because the function might delete--- the final item in the 'NEIntMap'). When used with trivial functors like--- 'Identity' and 'Const', it is often slightly slower than--- specialized 'lookup' and 'delete'. However, when the functor is--- non-trivial and key comparison is not particularly cheap, it is the--- fastest way.------ See 'alterF'' for a version that disallows deletion, and so therefore--- can return 'NEIntMap' and be used to implement 'insert'------ Note on rewrite rules:------ This module includes GHC rewrite rules to optimize 'alterF' for--- the 'Const' and 'Identity' functors. In general, these rules--- improve performance. The sole exception is that when using--- 'Identity', deleting a key that is already absent takes longer--- than it would without the rules. If you expect this to occur--- a very large fraction of the time, you might consider using a--- private copy of the 'Identity' type.------ Note: Unlike @Data.IntMap.alterF@ for 'IntMap', 'alterF' is /not/ a flipped--- version of the 'Control.Lens.At.at' combinator from "Control.Lens.At".--- However, it match the shape expected from most functions expecting--- lenses, getters, and setters, so can be thought of as a "psuedo-lens",--- with virtually the same practical applications as a legitimate lens.-alterF ::- Functor f =>- (Maybe a -> f (Maybe a)) ->- Key ->- NEIntMap a ->- f (IntMap a)-alterF f k n@(NEIntMap k0 v m) = case compare k k0 of- LT -> flip (maybe id (insertMinMap k)) (toMap n) <$> f Nothing- EQ -> flip (maybe id (insertMinMap k0)) m <$> f (Just v)- GT -> insertMinMap k0 v <$> M.alterF f k m-{-# INLINEABLE [2] alterF #-}---- if f ~ Const b, it's a lookup-{-# RULES-"alterF/Const" forall k (f :: Maybe a -> Const b (Maybe a)).- alterF f k =- Const . getConst . f . lookup k- #-}---- if f ~ Identity, it's an 'alter'-{-# RULES-"alterF/Identity" forall k (f :: Maybe a -> Identity (Maybe a)).- alterF f k =- Identity . alter (runIdentity . f) k- #-}---- | /O(log n)/. Variant of 'alter' that disallows deletion. Allows us to--- guarantee that the result is also a non-empty IntMap.-alter' ::- (Maybe a -> a) ->- Key ->- NEIntMap a ->- NEIntMap a-alter' f k n@(NEIntMap k0 v m) = case compare k k0 of- LT -> NEIntMap k (f Nothing) . toMap $ n- EQ -> NEIntMap k0 (f (Just v)) m- GT -> NEIntMap k0 v . M.alter (Just . f) k $ m-{-# INLINE alter' #-}---- | /O(log n)/. Variant of 'alterF' that disallows deletion. Allows us to--- guarantee that the result is also a non-empty IntMap.------ Like @Data.IntMap.alterF@ for 'IntMap', can be used to generalize and unify--- 'lookup' and 'insert'. However, because it disallows deletion, it--- cannot be used to implement 'delete'.------ See 'alterF' for usage information and caveats.------ Note: Neither 'alterF' nor 'alterF'' can be considered flipped versions--- of the 'Control.Lens.At.at' combinator from "Control.Lens.At". However,--- this can match the shape expected from most functions expecting lenses,--- getters, and setters, so can be thought of as a "psuedo-lens", with--- virtually the same practical applications as a legitimate lens.------ __WARNING__: The rewrite rule for 'Identity' exposes an inconsistency in--- undefined behavior for "Data.IntMap". @Data.IntMap.alterF@ will actually--- /maintain/ the original key in the map when used with 'Identity';--- however, @Data.IntMap.insertWith@ will /replace/ the orginal key in the--- map. The rewrite rule for 'alterF'' has chosen to be faithful to--- @Data.IntMap.insertWith@, and /not/ @Data.IntMap.alterF@, for the sake of--- a cleaner implementation.-alterF' ::- Functor f =>- (Maybe a -> f a) ->- Key ->- NEIntMap a ->- f (NEIntMap a)-alterF' f k n@(NEIntMap k0 v m) = case compare k k0 of- LT -> flip (NEIntMap k) (toMap n) <$> f Nothing- EQ -> flip (NEIntMap k0) m <$> f (Just v)- GT -> NEIntMap k0 v <$> M.alterF (fmap Just . f) k m-{-# INLINEABLE [2] alterF' #-}---- if f ~ Const b, it's a lookup-{-# RULES-"alterF'/Const" forall k (f :: Maybe a -> Const b a).- alterF' f k =- Const . getConst . f . lookup k- #-}---- if f ~ Identity, it's an insertWith-{-# RULES-"alterF'/Identity" forall k (f :: Maybe a -> Identity a).- alterF' f k =- Identity . insertWith (\_ -> runIdentity . f . Just) k (runIdentity (f Nothing))- #-}---- | /O(log n)/. Lookup the value at a key in the map.------ The function will return the corresponding value as @('Just' value)@,--- or 'Nothing' if the key isn't in the map.------ An example of using @lookup@:------ > import Prelude hiding (lookup)--- > import Data.Map.NonEmpty--- >--- > employeeDept = fromList (("John","Sales") :| [("Bob","IT")])--- > deptCountry = fromList (("IT","USA") :| [("Sales","France")])--- > countryCurrency = fromList (("USA", "Dollar") :| [("France", "Euro")])--- >--- > employeeCurrency :: String -> Maybe String--- > employeeCurrency name = do--- > dept <- lookup name employeeDept--- > country <- lookup dept deptCountry--- > lookup country countryCurrency--- >--- > main = do--- > putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))--- > putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))------ The output of this program:------ > John's currency: Just "Euro"--- > Pete's currency: Nothing-lookup ::- Key ->- NEIntMap a ->- Maybe a-lookup k (NEIntMap k0 v m) = case compare k k0 of- LT -> Nothing- EQ -> Just v- GT -> M.lookup k m-{-# INLINE lookup #-}---- | /O(log n)/. Find the value at a key. Returns 'Nothing' when the--- element can not be found.------ prop> fromList ((5, 'a') :| [(3, 'b')]) !? 1 == Nothing--- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 5 == Just 'a'-(!?) :: NEIntMap a -> Key -> Maybe a-(!?) = flip lookup-{-# INLINE (!?) #-}---- | /O(log n)/. Find the value at a key. Calls 'error' when the element--- can not be found.------ > fromList ((5,'a') :| [(3,'b')]) ! 1 Error: element not in the map--- > fromList ((5,'a') :| [(3,'b')]) ! 5 == 'a'-(!) :: NEIntMap a -> Key -> a-(!) m k = fromMaybe e $ m !? k- where- e = error "NEIntMap.!: given key is not an element in the map"-{-# INLINE (!) #-}--infixl 9 !?-infixl 9 !---- | /O(log n)/. The expression @('findWithDefault' def k map)@ returns--- the value at key @k@ or returns default value @def@--- when the key is not in the map.------ > findWithDefault 'x' 1 (fromList ((5,'a') :| [(3,'b')])) == 'x'--- > findWithDefault 'x' 5 (fromList ((5,'a') :| [(3,'b')])) == 'a'-findWithDefault ::- a ->- Key ->- NEIntMap a ->- a-findWithDefault def k (NEIntMap k0 v m) = case compare k k0 of- LT -> def- EQ -> v- GT -> M.findWithDefault def k m-{-# INLINE findWithDefault #-}---- | /O(log n)/. Is the key a member of the map? See also 'notMember'.------ > member 5 (fromList ((5,'a') :| [(3,'b')])) == True--- > member 1 (fromList ((5,'a') :| [(3,'b')])) == False-member :: Key -> NEIntMap a -> Bool-member k (NEIntMap k0 _ m) = case compare k k0 of- LT -> False- EQ -> True- GT -> M.member k m-{-# INLINE member #-}---- | /O(log n)/. Is the key not a member of the map? See also 'member'.------ > notMember 5 (fromList ((5,'a') :| [(3,'b')])) == False--- > notMember 1 (fromList ((5,'a') :| [(3,'b')])) == True-notMember :: Key -> NEIntMap a -> Bool-notMember k (NEIntMap k0 _ m) = case compare k k0 of- LT -> True- EQ -> False- GT -> M.notMember k m-{-# INLINE notMember #-}---- | /O(log n)/. Find largest key smaller than the given one and return the--- corresponding (key, value) pair.------ > lookupLT 3 (fromList ((3,'a') :| [(5,'b')])) == Nothing--- > lookupLT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')-lookupLT :: Key -> NEIntMap a -> Maybe (Key, a)-lookupLT k (NEIntMap k0 v m) = case compare k k0 of- LT -> Nothing- EQ -> Nothing- GT -> M.lookupLT k m <|> Just (k0, v)-{-# INLINE lookupLT #-}---- | /O(log n)/. Find smallest key greater than the given one and return the--- corresponding (key, value) pair.------ > lookupGT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')--- > lookupGT 5 (fromList ((3,'a') :| [(5,'b')])) == Nothing-lookupGT :: Key -> NEIntMap a -> Maybe (Key, a)-lookupGT k (NEIntMap k0 v m) = case compare k k0 of- LT -> Just (k0, v)- EQ -> M.lookupMin m- GT -> M.lookupGT k m-{-# INLINE lookupGT #-}---- | /O(log n)/. Find largest key smaller or equal to the given one and return--- the corresponding (key, value) pair.------ > lookupLE 2 (fromList ((3,'a') :| [(5,'b')])) == Nothing--- > lookupLE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')--- > lookupLE 5 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')-lookupLE :: Key -> NEIntMap a -> Maybe (Key, a)-lookupLE k (NEIntMap k0 v m) = case compare k k0 of- LT -> Nothing- EQ -> Just (k0, v)- GT -> M.lookupLE k m <|> Just (k0, v)-{-# INLINE lookupLE #-}---- | /O(log n)/. Find smallest key greater or equal to the given one and return--- the corresponding (key, value) pair.------ > lookupGE 3 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')--- > lookupGE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')--- > lookupGE 6 (fromList ((3,'a') :| [(5,'b')])) == Nothing-lookupGE :: Key -> NEIntMap a -> Maybe (Key, a)-lookupGE k (NEIntMap k0 v m) = case compare k k0 of- LT -> Just (k0, v)- EQ -> Just (k0, v)- GT -> M.lookupGE k m-{-# INLINE lookupGE #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union with a combining function.------ > unionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "aA"), (7, "C")])-unionWith ::- (a -> a -> a) ->- NEIntMap a ->- NEIntMap a ->- NEIntMap a-unionWith f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of- LT -> NEIntMap k1 v1 . M.unionWith f m1 . toMap $ n2- EQ -> NEIntMap k1 (f v1 v2) . M.unionWith f m1 $ m2- GT -> NEIntMap k2 v2 . M.unionWith f (toMap n1) $ m2-{-# INLINE unionWith #-}---- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a possibly-empty--- 'IntMap' and a non-empty map.------ @since 0.3.6.0-unionMapLeft :: IntMap a -> NEIntMap a -> NEIntMap a-unionMapLeft m n = withNonEmpty n (`union` n) m-{-# INLINE unionMapLeft #-}---- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a non-empty map and a--- possibly-empty 'IntMap'.------ @since 0.3.6.0-unionMapRight :: NEIntMap a -> IntMap a -> NEIntMap a-unionMapRight n = withNonEmpty n (union n)-{-# INLINE unionMapRight #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'IntMap' and a--- non-empty map with a combining function.------ @since 0.3.6.0-unionMapWithLeft :: (a -> a -> a) -> IntMap a -> NEIntMap a -> NEIntMap a-unionMapWithLeft f m n = withNonEmpty n (\m' -> unionWith f m' n) m-{-# INLINE unionMapWithLeft #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a--- possibly-empty 'IntMap' with a combining function.------ @since 0.3.6.0-unionMapWithRight :: (a -> a -> a) -> NEIntMap a -> IntMap a -> NEIntMap a-unionMapWithRight f n = withNonEmpty n (unionWith f n)-{-# INLINE unionMapWithRight #-}---- | /O(m*log(n\/m + 1)), m <= n/.--- Union with a combining function, given the matching key.------ > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value--- > unionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "5:a|A"), (7, "C")])-unionWithKey ::- (Key -> a -> a -> a) ->- NEIntMap a ->- NEIntMap a ->- NEIntMap a-unionWithKey f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of- LT -> NEIntMap k1 v1 . M.unionWithKey f m1 . toMap $ n2- EQ -> NEIntMap k1 (f k1 v1 v2) . M.unionWithKey f m1 $ m2- GT -> NEIntMap k2 v2 . M.unionWithKey f (toMap n1) $ m2-{-# INLINE unionWithKey #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'IntMap' and a--- non-empty map with a combining function, given the matching key.------ @since 0.3.6.0-unionMapWithKeyLeft ::- (Key -> a -> a -> a) ->- IntMap a ->- NEIntMap a ->- NEIntMap a-unionMapWithKeyLeft f m n = withNonEmpty n (\m' -> unionWithKey f m' n) m-{-# INLINE unionMapWithKeyLeft #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a--- possibly-empty 'IntMap' with a combining function, given the matching key.------ @since 0.3.6.0-unionMapWithKeyRight ::- (Key -> a -> a -> a) ->- NEIntMap a ->- IntMap a ->- NEIntMap a-unionMapWithKeyRight f n = withNonEmpty n (unionWithKey f n)-{-# INLINE unionMapWithKeyRight #-}---- | The union of a non-empty list of maps, with a combining operation:--- (@'unionsWith' f == 'Data.Foldable.foldl1' ('unionWith' f)@).------ > unionsWith (++) (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])--- > == fromList ((3, "bB3") :| [(5, "aAA3"), (7, "C")])-unionsWith ::- Foldable1 f =>- (a -> a -> a) ->- f (NEIntMap a) ->- NEIntMap a-unionsWith f (F1.toNonEmpty -> (m :| ms)) = F.foldl' (unionWith f) m ms-{-# INLINE unionsWith #-}---- | /O(m*log(n\/m + 1)), m <= n/. Difference of two maps.--- Return elements of the first map not existing in the second map.------ Returns a potentially empty map ('IntMap'), in case the first map is--- a subset of the second map.------ > difference (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 3 "b"-difference ::- NEIntMap a ->- NEIntMap b ->- IntMap a-difference n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 _ m2) = case compare k1 k2 of- -- k1 is not in n2, so cannot be deleted- LT -> insertMinMap k1 v1 $ m1 `M.difference` toMap n2- -- k2 deletes k1, and only k1- EQ -> m1 `M.difference` m2- -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.- GT -> toMap n1 `M.difference` m2-{-# INLINE difference #-}---- | Same as 'difference'.-(\\) ::- NEIntMap a ->- NEIntMap b ->- IntMap a-(\\) = difference-{-# INLINE (\\) #-}---- | /O(n+m)/. Difference with a combining function.--- When two equal keys are--- encountered, the combining function is applied to the values of these keys.--- 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@.------ Returns a potentially empty map ('IntMap'), in case the first map is--- a subset of the second map and the function returns 'Nothing' for every--- pair.------ > let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing--- > differenceWith f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (7, "C")]))--- > == Data.IntMap.singleton 3 "b:B"-differenceWith ::- (a -> b -> Maybe a) ->- NEIntMap a ->- NEIntMap b ->- IntMap a-differenceWith f = differenceWithKey (const f)-{-# INLINE differenceWith #-}---- | /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@.------ Returns a potentially empty map ('IntMap'), in case the first map is--- a subset of the second map and the function returns 'Nothing' for every--- pair.------ > let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing--- > differenceWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (10, "C")]))--- > == Data.IntMap.singleton 3 "3:b|B"-differenceWithKey ::- (Key -> a -> b -> Maybe a) ->- NEIntMap a ->- NEIntMap b ->- IntMap a-differenceWithKey f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of- -- k1 is not in n2, so cannot be deleted- LT -> insertMinMap k1 v1 $ M.differenceWithKey f m1 (toMap n2)- -- k2 deletes k1, and only k1- EQ -> maybe id (insertMinMap k1) (f k1 v1 v2) (M.differenceWithKey f m1 m2)- -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.- GT -> M.differenceWithKey f (toMap n1) m2-{-# INLINE differenceWithKey #-}---- | /O(m*log(n\/m + 1)), m <= n/. Intersection of two maps.--- Return data in the first map for the keys existing in both maps.--- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).------ Returns a potentially empty map ('IntMap'), in case the two maps share no--- keys in common.------ > intersection (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 5 "a"-intersection ::- NEIntMap a ->- NEIntMap b ->- IntMap a-intersection n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 _ m2) = case compare k1 k2 of- -- k1 is not in n2- LT -> m1 `M.intersection` toMap n2- -- k1 and k2 are a part of the result- EQ -> insertMinMap k1 v1 $ m1 `M.intersection` m2- -- k2 is not in n1- GT -> toMap n1 `M.intersection` m2-{-# INLINE intersection #-}---- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.------ Returns a potentially empty map ('IntMap'), in case the two maps share no--- keys in common.------ > intersectionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 5 "aA"-intersectionWith ::- (a -> b -> c) ->- NEIntMap a ->- NEIntMap b ->- IntMap c-intersectionWith f = intersectionWithKey (const f)-{-# INLINE intersectionWith #-}---- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.------ Returns a potentially empty map ('IntMap'), in case the two maps share no--- keys in common.------ > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar--- > intersectionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 5 "5:a|A"-intersectionWithKey ::- (Key -> a -> b -> c) ->- NEIntMap a ->- NEIntMap b ->- IntMap c-intersectionWithKey f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of- -- k1 is not in n2- LT -> M.intersectionWithKey f m1 (toMap n2)- -- k1 and k2 are a part of the result- EQ -> insertMinMap k1 (f k1 v1 v2) $ M.intersectionWithKey f m1 m2- -- k2 is not in n1- GT -> M.intersectionWithKey f (toMap n1) m2-{-# INLINE intersectionWithKey #-}---- | /O(n)/. IntMap a function over all values in the map.------ > let f key x = (show key) ++ ":" ++ x--- > mapWithKey f (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "3:b") :| [(5, "5:a")])-mapWithKey :: (Key -> a -> b) -> NEIntMap a -> NEIntMap b-mapWithKey f (NEIntMap k v m) = NEIntMap k (f k v) (M.mapWithKey f m)-{-# NOINLINE [1] mapWithKey #-}--{-# RULES-"mapWithKey/mapWithKey" forall f g xs.- mapWithKey f (mapWithKey g xs) =- mapWithKey (\k a -> f k (g k a)) xs-"mapWithKey/map" forall f g xs.- mapWithKey f (map g xs) =- mapWithKey (\k a -> f k (g a)) xs-"map/mapWithKey" forall f g xs.- map f (mapWithKey g xs) =- mapWithKey (\k a -> f (g k a)) xs- #-}---- | /O(n)/. The function 'mapAccum' threads an accumulating argument--- through the map in ascending order of keys.------ > let f a b = (a ++ b, b ++ "X")--- > mapAccum f "Everything: " (fromList ((5,"a") :| [(3,"b")])) == ("Everything: ba", fromList ((3, "bX") :| [(5, "aX")]))-mapAccum ::- (a -> b -> (a, c)) ->- a ->- NEIntMap b ->- (a, NEIntMap c)-mapAccum f = mapAccumWithKey (\x _ -> f x)-{-# INLINE mapAccum #-}---- | /O(n)/. The function 'mapAccumWithKey' threads an accumulating--- argument through the map in ascending order of keys.------ > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")--- > mapAccumWithKey f "Everything:" (fromList ((5,"a") :| [(3,"b")])) == ("Everything: 3-b 5-a", fromList ((3, "bX") :| [(5, "aX")]))-mapAccumWithKey ::- (a -> Key -> b -> (a, c)) ->- a ->- NEIntMap b ->- (a, NEIntMap c)-mapAccumWithKey f z0 (NEIntMap k v m) = (z2, NEIntMap k v' m')- where- ~(z1, v') = f z0 k v- ~(z2, m') = M.mapAccumWithKey f z1 m-{-# INLINE mapAccumWithKey #-}---- | /O(n)/. The function 'mapAccumRWithKey' threads an accumulating--- argument through the map in descending order of keys.-mapAccumRWithKey ::- (a -> Key -> b -> (a, c)) ->- a ->- NEIntMap b ->- (a, NEIntMap c)-mapAccumRWithKey f z0 (NEIntMap k v m) = (z2, NEIntMap k v' m')- where- ~(z1, m') = M.mapAccumRWithKey f z0 m- ~(z2, v') = f z1 k v-{-# INLINE mapAccumRWithKey #-}---- | /O(n*log n)/.--- @'mapKeys' 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 value at the greatest of the--- original keys is retained.------ While the size of the result map may be smaller than the input map, the--- output map is still guaranteed to be non-empty if the input map is--- non-empty.------ > mapKeys (+ 1) (fromList ((5,"a") :| [(3,"b")])) == fromList ((4, "b") :| [(6, "a")])--- > mapKeys (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "c"--- > mapKeys (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "c"-mapKeys ::- (Key -> Key) ->- NEIntMap a ->- NEIntMap a-mapKeys f (NEIntMap k0 v0 m) =- fromListWith const- . ((f k0, v0) :|)- . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []- $ m-{-# INLINEABLE mapKeys #-}---- | /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@. The value at the greater of the two original keys--- is used as the first argument to @c@.------ While the size of the result map may be smaller than the input map, the--- output map is still guaranteed to be non-empty if the input map is--- non-empty.------ > mapKeysWith (++) (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "cdab"--- > mapKeysWith (++) (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "cdab"-mapKeysWith ::- (a -> a -> a) ->- (Key -> Key) ->- NEIntMap a ->- NEIntMap a-mapKeysWith c f (NEIntMap k0 v0 m) =- fromListWith c- . ((f k0, v0) :|)- . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []- $ m-{-# INLINEABLE mapKeysWith #-}---- | /O(n)/.--- @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@--- is strictly monotonic.--- 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]--- > ==> mapKeysMonotonic f s == mapKeys f s--- > where ls = keys s------ This means that @f@ maps distinct original keys to distinct resulting keys.--- This function has better performance than 'mapKeys'.------ While the size of the result map may be smaller than the input map, the--- output map is still guaranteed to be non-empty if the input map is--- non-empty.------ > mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")])) == fromList ((6, "b") :| [(10, "a")])--- > valid (mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")]))) == True--- > valid (mapKeysMonotonic (\ _ -> 1) (fromList ((5,"a") :| [(3,"b")]))) == False-mapKeysMonotonic ::- (Key -> Key) ->- NEIntMap a ->- NEIntMap a-mapKeysMonotonic f (NEIntMap k v m) =- NEIntMap (f k) v- . M.mapKeysMonotonic f- $ m-{-# INLINE mapKeysMonotonic #-}---- | /O(n)/. Fold the keys and values in the map using the given right-associative--- binary operator, such that--- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.------ For example,------ > keysList map = foldrWithKey (\k x ks -> k:ks) [] map-foldrWithKey :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b-foldrWithKey f z (NEIntMap k v m) = f k v . M.foldrWithKey f z $ m-{-# INLINE foldrWithKey #-}---- | /O(n)/. Fold the keys and values in the map using the given left-associative--- binary operator, such that--- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.------ For example,------ > keysList = reverse . foldlWithKey (\ks k x -> k:ks) []-foldlWithKey :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a-foldlWithKey f z (NEIntMap k v m) = M.foldlWithKey f (f z k v) m-{-# INLINE foldlWithKey #-}---- | /O(n)/. A strict version of 'foldr1'. Each application of the operator--- is evaluated before using the result in the next application. This--- function is strict in the starting value.-foldr1' :: (a -> a -> a) -> NEIntMap a -> a-foldr1' f (NEIntMap _ v m) = case M.maxView m of- Nothing -> v- Just (y, m') -> let !z = M.foldr' f y m' in v `f` z-{-# INLINE foldr1' #-}---- | /O(n)/. A strict version of 'foldl1'. Each application of the operator--- is evaluated before using the result in the next application. This--- function is strict in the starting value.-foldl1' :: (a -> a -> a) -> NEIntMap a -> a-foldl1' f (NEIntMap _ v m) = M.foldl' f v m-{-# INLINE foldl1' #-}---- | /O(n)/. A strict version of 'foldrWithKey'. Each application of the operator is--- evaluated before using the result in the next application. This--- function is strict in the starting value.-foldrWithKey' :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b-foldrWithKey' f z (NEIntMap k v m) = f k v y- where- !y = M.foldrWithKey f z m-{-# INLINE foldrWithKey' #-}---- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is--- evaluated before using the result in the next application. This--- function is strict in the starting value.-foldlWithKey' :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a-foldlWithKey' f z (NEIntMap k v m) = M.foldlWithKey' f x m- where- !x = f z k v-{-# INLINE foldlWithKey' #-}---- | /O(n)/. Return all keys of the map in ascending order.------ > keys (fromList ((5,"a") :| [(3,"b")])) == (3 :| [5])-keys :: NEIntMap a -> NonEmpty Key-keys (NEIntMap k _ m) = k :| M.keys m-{-# INLINE keys #-}---- | /O(n)/. An alias for 'toAscList'. Return all key\/value pairs in the map--- in ascending key order.------ > assocs (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])-assocs :: NEIntMap a -> NonEmpty (Key, a)-assocs = toList-{-# INLINE assocs #-}---- | /O(n)/. The non-empty set of all keys of the map.------ > keysSet (fromList ((5,"a") :| [(3,"b")])) == Data.Set.NonEmpty.fromList (3 :| [5])-keysSet :: NEIntMap a -> NEIntSet-keysSet (NEIntMap k _ m) = NEIntSet k (M.keysSet m)-{-# INLINE keysSet #-}---- | /O(n)/. Convert the map to a list of key\/value pairs where the keys are--- in ascending order.------ > toAscList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])-toAscList :: NEIntMap a -> NonEmpty (Key, a)-toAscList = toList-{-# INLINE toAscList #-}---- | /O(n)/. Convert the map to a list of key\/value pairs where the keys--- are in descending order.------ > toDescList (fromList ((5,"a") :| [(3,"b")])) == ((5,"a") :| [(3,"b")])-toDescList :: NEIntMap a -> NonEmpty (Key, a)-toDescList (NEIntMap k0 v0 m) = M.foldlWithKey' go ((k0, v0) :| []) m- where- go xs k v = (k, v) NE.<| xs-{-# INLINE toDescList #-}---- | /O(n)/. Filter all values that satisfy the predicate.------ Returns a potentially empty map ('IntMap'), because we could--- potentailly filter out all items in the original 'NEIntMap'.------ > filter (> "a") (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"--- > filter (> "x") (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.empty--- > filter (< "a") (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.empty-filter ::- (a -> Bool) ->- NEIntMap a ->- IntMap a-filter f (NEIntMap k v m)- | f v = insertMinMap k v . M.filter f $ m- | otherwise = M.filter f m-{-# INLINE filter #-}---- | /O(n)/. Filter all keys\/values that satisfy the predicate.------ Returns a potentially empty map ('IntMap'), because we could--- potentailly filter out all items in the original 'NEIntMap'.------ > filterWithKey (\k _ -> k > 4) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"-filterWithKey ::- (Key -> a -> Bool) ->- NEIntMap a ->- IntMap a-filterWithKey f (NEIntMap k v m)- | f k v = insertMinMap k v . M.filterWithKey f $ m- | otherwise = M.filterWithKey f m-{-# INLINE filterWithKey #-}---- | /O(m*log(n\/m + 1)), m <= n/. Restrict an 'NEIntMap' to only those keys--- found in a 'Data.Set.Set'.------ @--- m \`restrictKeys\` s = 'filterWithKey' (\k _ -> k ``Set.member`` s) m--- m \`restrictKeys\` s = m ``intersection`` 'fromSet' (const ()) s--- @-restrictKeys ::- NEIntMap a ->- IntSet ->- IntMap a-restrictKeys n@(NEIntMap k v m) xs = case S.minView xs of- Nothing -> M.empty- Just (y, ys) -> case compare k y of- -- k is not in xs- LT -> m `M.restrictKeys` xs- -- k and y are a part of the result- EQ -> insertMinMap k v $ m `M.restrictKeys` ys- -- y is not in m- GT -> toMap n `M.restrictKeys` ys-{-# INLINE restrictKeys #-}---- | /O(m*log(n\/m + 1)), m <= n/. Remove all keys in a 'Data.Set.Set' from--- an 'NEIntMap'.------ @--- m \`withoutKeys\` s = 'filterWithKey' (\k _ -> k ``Set.notMember`` s) m--- m \`withoutKeys\` s = m ``difference`` 'fromSet' (const ()) s--- @-withoutKeys ::- NEIntMap a ->- IntSet ->- IntMap a-withoutKeys n@(NEIntMap k v m) xs = case S.minView xs of- Nothing -> toMap n- Just (y, ys) -> case compare k y of- -- k is not in xs, so cannot be deleted- LT -> insertMinMap k v $ m `M.withoutKeys` xs- -- y deletes k, and only k- EQ -> m `M.withoutKeys` ys- -- y is not in n, so cannot delete anything, so we can just difference n and ys- GT -> toMap n `M.withoutKeys` ys-{-# INLINE withoutKeys #-}---- | /O(n)/. Partition the map according to a predicate.------ Returns a 'These' with potentially two non-empty maps:------ * @'This' n1@ means that the predicate was true for all items.--- * @'That' n2@ means that the predicate was false for all items.--- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the--- predicate) and @n2@ (all of the items that were false for the--- predicate).------ See also 'split'.------ > partition (> "a") (fromList ((5,"a") :| [(3,"b")])) == These (singleton 3 "b") (singleton 5 "a")--- > partition (< "x") (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))--- > partition (> "x") (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))-partition ::- (a -> Bool) ->- NEIntMap a ->- These (NEIntMap a) (NEIntMap a)-partition f = partitionWithKey (const f)-{-# INLINE partition #-}---- | /O(n)/. Partition the map according to a predicate.------ Returns a 'These' with potentially two non-empty maps:------ * @'This' n1@ means that the predicate was true for all items,--- returning the original map.--- * @'That' n2@ means that the predicate was false for all items,--- returning the original map.--- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the--- predicate) and @n2@ (all of the items that were false for the--- predicate).------ See also 'split'.------ > partitionWithKey (\ k _ -> k > 3) (fromList ((5,"a") :| [(3,"b")])) == These (singleton 5 "a") (singleton 3 "b")--- > partitionWithKey (\ k _ -> k < 7) (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))--- > partitionWithKey (\ k _ -> k > 7) (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))-partitionWithKey ::- (Key -> a -> Bool) ->- NEIntMap a ->- These (NEIntMap a) (NEIntMap a)-partitionWithKey f n@(NEIntMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing)- | f k v -> This n- | otherwise -> That n- (Just n1, Nothing)- | f k v -> This n- | otherwise -> These n1 (singleton k v)- (Nothing, Just n2)- | f k v -> These (singleton k v) n2- | otherwise -> That n- (Just n1, Just n2)- | f k v -> These (insertMapMin k v m1) n2- | otherwise -> These n1 (insertMapMin k v m2)- where- (m1, m2) = M.partitionWithKey f m0-{-# INLINEABLE partitionWithKey #-}---- | /O(n)/. Map values and collect the 'Just' results.------ Returns a potentially empty map ('IntMap'), because the function could--- potentially return 'Nothing' on all items in the 'NEIntMap'.------ > let f x = if x == "a" then Just "new a" else Nothing--- > mapMaybe f (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "new a"-mapMaybe ::- (a -> Maybe b) ->- NEIntMap a ->- IntMap b-mapMaybe f = mapMaybeWithKey (const f)-{-# INLINE mapMaybe #-}---- | /O(n)/. Map keys\/values and collect the 'Just' results.------ Returns a potentially empty map ('IntMap'), because the function could--- potentially return 'Nothing' on all items in the 'NEIntMap'.------ > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing--- > mapMaybeWithKey f (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "key : 3"-mapMaybeWithKey ::- (Key -> a -> Maybe b) ->- NEIntMap a ->- IntMap b-mapMaybeWithKey f (NEIntMap k v m) = maybe id (insertMinMap k) (f k v) (M.mapMaybeWithKey f m)-{-# INLINE mapMaybeWithKey #-}---- | /O(n)/. Map values and separate the 'Left' and 'Right' results.------ Returns a 'These' with potentially two non-empty maps:------ * @'This' n1@ means that the results were all 'Left'.--- * @'That' n2@ means that the results were all 'Right'.--- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')--- and @n2@ (the map where the results were 'Right')------ > let f a = if a < "c" then Left a else Right a--- > mapEither f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))--- > == These (fromList ((3,"b") :| [(5,"a")])) (fromList ((1,"x") :| [(7,"z")]))--- >--- > mapEither (\ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))--- > == That (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))-mapEither ::- (a -> Either b c) ->- NEIntMap a ->- These (NEIntMap b) (NEIntMap c)-mapEither f = mapEitherWithKey (const f)-{-# INLINE mapEither #-}---- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results.------ Returns a 'These' with potentially two non-empty maps:------ * @'This' n1@ means that the results were all 'Left'.--- * @'That' n2@ means that the results were all 'Right'.--- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')--- and @n2@ (the map where the results were 'Right')------ > let f k a = if k < 5 then Left (k * 2) else Right (a ++ a)--- > mapEitherWithKey f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))--- > == These (fromList ((1,2) :| [(3,6)])) (fromList ((5,"aa") :| [(7,"zz")]))--- >--- > mapEitherWithKey (\_ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))--- > == That (fromList ((1,"x") :| [(3,"b"), (5,"a"), (7,"z")]))-mapEitherWithKey ::- (Key -> a -> Either b c) ->- NEIntMap a ->- These (NEIntMap b) (NEIntMap c)-mapEitherWithKey f (NEIntMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing) -> case f k v of- Left v' -> This (singleton k v')- Right v' -> That (singleton k v')- (Just n1, Nothing) -> case f k v of- Left v' -> This (insertMapMin k v' m1)- Right v' -> These n1 (singleton k v')- (Nothing, Just n2) -> case f k v of- Left v' -> These (singleton k v') n2- Right v' -> That (insertMapMin k v' m2)- (Just n1, Just n2) -> case f k v of- Left v' -> These (insertMapMin k v' m1) n2- Right v' -> These n1 (insertMapMin k v' m2)- where- (m1, m2) = M.mapEitherWithKey f m0-{-# INLINEABLE mapEitherWithKey #-}---- | /O(log n)/. The expression (@'split' k map@) is potentially a 'These'--- containing up to two 'NEIntMap's based on splitting the map into maps--- containing items before and after the given key @k@. It will never--- return a map that contains @k@ itself.------ * 'Nothing' means that @k@ was the only key in the the original map,--- and so there are no items before or after it.--- * @'Just' ('This' n1)@ means @k@ was larger than or equal to all items--- in the map, and @n1@ is the entire original map (minus @k@, if it was--- present)--- * @'Just' ('That' n2)@ means @k@ was smaller than or equal to all--- items in the map, and @n2@ is the entire original map (minus @k@, if--- it was present)--- * @'Just' ('These' n1 n2)@ gives @n1@ (the map of all keys from the--- original map less than @k@) and @n2@ (the map of all keys from the--- original map greater than @k@)------ > split 2 (fromList ((5,"a") :| [(3,"b")])) == Just (That (fromList ((3,"b") :| [(5,"a")])) )--- > split 3 (fromList ((5,"a") :| [(3,"b")])) == Just (That (singleton 5 "a") )--- > split 4 (fromList ((5,"a") :| [(3,"b")])) == Just (These (singleton 3 "b") (singleton 5 "a"))--- > split 5 (fromList ((5,"a") :| [(3,"b")])) == Just (This (singleton 3 "b") )--- > split 6 (fromList ((5,"a") :| [(3,"b")])) == Just (This (fromList ((3,"b") :| [(5,"a")])) )--- > split 5 (singleton 5 "a") == Nothing-split ::- Key ->- NEIntMap a ->- Maybe (These (NEIntMap a) (NEIntMap a))-split k n@(NEIntMap k0 v m0) = case compare k k0 of- LT -> Just $ That n- EQ -> That <$> nonEmptyMap m0- GT -> Just $ case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing) -> This (singleton k0 v)- (Just _, Nothing) -> This (insertMapMin k0 v m1)- (Nothing, Just n2) -> These (singleton k0 v) n2- (Just _, Just n2) -> These (insertMapMin k0 v m1) n2- where- (m1, m2) = M.split k m0-{-# INLINEABLE split #-}---- | /O(log n)/. The expression (@'splitLookup' k map@) splits a map just--- like 'split' but also returns @'lookup' k map@, as the first field in--- the 'These':------ > splitLookup 2 (fromList ((5,"a") :| [(3,"b")])) == That (That (fromList ((3,"b") :| [(5,"a")])))--- > splitLookup 3 (fromList ((5,"a") :| [(3,"b")])) == These "b" (That (singleton 5 "a"))--- > splitLookup 4 (fromList ((5,"a") :| [(3,"b")])) == That (These (singleton 3 "b") (singleton 5 "a"))--- > splitLookup 5 (fromList ((5,"a") :| [(3,"b")])) == These "a" (This (singleton 3 "b"))--- > splitLookup 6 (fromList ((5,"a") :| [(3,"b")])) == That (This (fromList ((3,"b") :| [(5,"a")])))--- > splitLookup 5 (singleton 5 "a") == This "a"-splitLookup ::- Key ->- NEIntMap a ->- These a (These (NEIntMap a) (NEIntMap a))-splitLookup k n@(NEIntMap k0 v0 m0) = case compare k k0 of- LT -> That . That $ n- EQ -> maybe (This v0) (These v0 . That) . nonEmptyMap $ m0- GT -> maybe That These v $ case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing) -> This (singleton k0 v0)- (Just _, Nothing) -> This (insertMapMin k0 v0 m1)- (Nothing, Just n2) -> These (singleton k0 v0) n2- (Just _, Just n2) -> These (insertMapMin k0 v0 m1) n2- where- (m1, v, m2) = M.splitLookup k m0-{-# INLINEABLE splitLookup #-}---- | /O(1)/. Decompose a map into pieces based on the structure of the--- underlying tree. This function is useful for consuming a map in--- parallel.------ No guarantee is made as to the sizes of the pieces; an internal, but--- deterministic process determines this. However, it is guaranteed that--- the pieces returned will be in ascending order (all elements in the--- first submap less than all elements in the second, and so on).------ Note that the current implementation does not return more than four--- submaps, but you should not depend on this behaviour because it can--- change in the future without notice.-splitRoot ::- NEIntMap a ->- NonEmpty (NEIntMap a)-splitRoot (NEIntMap k v m) =- singleton k v- :| Maybe.mapMaybe nonEmptyMap (M.splitRoot m)-{-# INLINE splitRoot #-}---- | /O(m*log(n\/m + 1)), m <= n/.--- This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).-isSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool-isSubmapOf = isSubmapOfBy (==)-{-# INLINE isSubmapOf #-}---- | /O(m*log(n\/m + 1)), m <= n/.--- The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if--- all keys in @t1@ are in tree @t2@, and when @f@ returns 'True' when--- applied to their respective values. For example, the following--- expressions are all 'True':------ > isSubmapOfBy (==) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))--- > isSubmapOfBy (<=) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))--- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (fromList (('a',1) :| [('b',2)]))------ But the following are all 'False':------ > isSubmapOfBy (==) (singleton 'a' 2) (fromList (('a',1) :| [('b',2)]))--- > isSubmapOfBy (<) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))--- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (singleton 'a' 1)-isSubmapOfBy ::- (a -> b -> Bool) ->- NEIntMap a ->- NEIntMap b ->- Bool-isSubmapOfBy f (NEIntMap k v m0) (toMap -> m1) =- kvSub- && M.isSubmapOfBy f m0 m1- where- kvSub = case M.lookup k m1 of- Just v0 -> f v v0- Nothing -> False-{-# INLINE isSubmapOfBy #-}---- | /O(m*log(n\/m + 1)), m <= n/. Is this a proper submap? (ie. a submap--- but not equal). Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy'--- (==)@).-isProperSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool-isProperSubmapOf = isProperSubmapOfBy (==)-{-# INLINE isProperSubmapOf #-}---- | /O(m*log(n\/m + 1)), m <= n/. 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 values. For--- example, the following expressions are all 'True':------ > isProperSubmapOfBy (==) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))--- > isProperSubmapOfBy (<=) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))------ But the following are all 'False':------ > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (fromList ((1,1) :| [(2,2)]))--- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (singleton 1 1))--- > isProperSubmapOfBy (<) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))-isProperSubmapOfBy ::- (a -> b -> Bool) ->- NEIntMap a ->- NEIntMap b ->- Bool-isProperSubmapOfBy f m1 m2 =- M.size (neimIntMap m1) < M.size (neimIntMap m2)- && isSubmapOfBy f m1 m2-{-# INLINE isProperSubmapOfBy #-}---- | /O(1)/. The minimal key of the map. Note that this is total, making--- 'Data.IntMap.lookupMin' obsolete. It is constant-time, so has better--- asymptotics than @Data.IntMap.lookupMin@ and @Data.IntMap.findMin@, as well.------ > findMin (fromList ((5,"a") :| [(3,"b")])) == (3,"b")-findMin :: NEIntMap a -> (Key, a)-findMin (NEIntMap k v _) = (k, v)-{-# INLINE findMin #-}---- | /O(log n)/. The maximal key of the map. Note that this is total, making--- 'Data.IntMap.lookupMin' obsolete.------ > findMax (fromList ((5,"a") :| [(3,"b")])) == (5,"a")-findMax :: NEIntMap a -> (Key, a)-findMax (NEIntMap k v m) = fromMaybe (k, v) . M.lookupMax $ m-{-# INLINE findMax #-}---- | /O(1)/. Delete the minimal key. Returns a potentially empty map--- ('IntMap'), because we might end up deleting the final key in a singleton--- map. It is constant-time, so has better asymptotics than--- 'Data.IntMap.deleteMin'.------ > deleteMin (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.IntMap.fromList [(5,"a"), (7,"c")]--- > deleteMin (singleton 5 "a") == Data.IntMap.empty-deleteMin :: NEIntMap a -> IntMap a-deleteMin (NEIntMap _ _ m) = m-{-# INLINE deleteMin #-}---- | /O(log n)/. Delete the maximal key. Returns a potentially empty map--- ('IntMap'), because we might end up deleting the final key in a singleton--- map.------ > deleteMax (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.IntMap.fromList [(3,"b"), (5,"a")]--- > deleteMax (singleton 5 "a") == Data.IntMap.empty-deleteMax :: NEIntMap a -> IntMap a-deleteMax (NEIntMap k v m) = case M.maxView m of- Nothing -> M.empty- Just (_, m') -> insertMinMap k v m'-{-# INLINE deleteMax #-}---- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the--- minimal key. Returns a potentially empty map ('IntMap'), because we might--- end up deleting the final key in the map if the function returns--- 'Nothing'. See 'adjustMin' for a version that can guaruntee that we--- return a non-empty map.------ > updateMin (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "Xb"), (5, "a")]--- > updateMin (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"-updateMin :: (a -> Maybe a) -> NEIntMap a -> IntMap a-updateMin f = updateMinWithKey (const f)-{-# INLINE updateMin #-}---- | /O(1)/. A version of 'updateMin' that disallows deletion, allowing us--- to guarantee that the result is also non-empty.-adjustMin :: (a -> a) -> NEIntMap a -> NEIntMap a-adjustMin f = adjustMinWithKey (const f)-{-# INLINE adjustMin #-}---- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the--- minimal key. Returns a potentially empty map ('IntMap'), because we might--- end up deleting the final key in the map if the function returns--- 'Nothing'. See 'adjustMinWithKey' for a version that guaruntees--- a non-empty map.------ > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3,"3:b"), (5,"a")]--- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"-updateMinWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a-updateMinWithKey f (NEIntMap k v m) = maybe id (insertMinMap k) (f k v) m-{-# INLINE updateMinWithKey #-}---- | /O(1)/. A version of 'adjustMaxWithKey' that disallows deletion,--- allowing us to guarantee that the result is also non-empty. Note that--- it also is able to have better asymptotics than 'updateMinWithKey' in--- general.-adjustMinWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a-adjustMinWithKey f (NEIntMap k v m) = NEIntMap k (f k v) m-{-# INLINE adjustMinWithKey #-}---- | /O(log n)/. Update the value at the maximal key. Returns--- a potentially empty map ('IntMap'), because we might end up deleting the--- final key in the map if the function returns 'Nothing'. See 'adjustMax'--- for a version that can guarantee that we return a non-empty map.------ > updateMax (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "Xa")]--- > updateMax (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"-updateMax :: (a -> Maybe a) -> NEIntMap a -> IntMap a-updateMax f = updateMaxWithKey (const f)-{-# INLINE updateMax #-}---- | /O(log n)/. A version of 'updateMax' that disallows deletion, allowing--- us to guarantee that the result is also non-empty.-adjustMax :: (a -> a) -> NEIntMap a -> NEIntMap a-adjustMax f = adjustMaxWithKey (const f)-{-# INLINE adjustMax #-}---- | /O(log n)/. Update the value at the maximal key. Returns--- a potentially empty map ('IntMap'), because we might end up deleting the--- final key in the map if the function returns 'Nothing'. See--- 'adjustMaxWithKey' for a version that guaruntees a non-empty map.------ > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3,"3:b"), (5,"a")]--- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"-updateMaxWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a-updateMaxWithKey f (NEIntMap k v m)- | M.null m = maybe m (M.singleton k) $ f k v- | otherwise =- insertMinMap k v- . M.updateMaxWithKey f- $ m-{-# INLINE updateMaxWithKey #-}---- | /O(log n)/. A version of 'updateMaxWithKey' that disallows deletion,--- allowing us to guarantee that the result is also non-empty.-adjustMaxWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a-adjustMaxWithKey f (NEIntMap k0 v m)- | M.null m = NEIntMap k0 (f k0 v) m- | otherwise =- insertMapMin k0 v- . M.updateMaxWithKey (\k -> Just . f k)- $ m-{-# INLINE adjustMaxWithKey #-}---- | /O(1)/. Retrieves the value associated with minimal key of the--- map, and the map stripped of that element. It is constant-time, so has--- better asymptotics than @Data.IntMap.minView@ for 'IntMap'.------ Note that unlike @Data.IntMap.minView@ for 'IntMap', this cannot ever fail,--- so doesn't need to return in a 'Maybe'. However, the result 'IntMap' is--- potentially empty, since the original map might have contained just--- a single item.------ > minView (fromList ((5,"a") :| [(3,"b")])) == ("b", Data.IntMap.singleton 5 "a")-minView :: NEIntMap a -> (a, IntMap a)-minView = first snd . deleteFindMin-{-# INLINE minView #-}---- | /O(1)/. Delete and find the minimal key-value pair. It is--- constant-time, so has better asymptotics that @Data.IntMap.minView@ for--- 'IntMap'.------ Note that unlike @Data.IntMap.deleteFindMin@ for 'IntMap', this cannot ever--- fail, and so is a total function. However, the result 'IntMap' is--- potentially empty, since the original map might have contained just--- a single item.------ > deleteFindMin (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((3,"b"), Data.IntMap.fromList [(5,"a"), (10,"c")])-deleteFindMin :: NEIntMap a -> ((Key, a), IntMap a)-deleteFindMin (NEIntMap k v m) = ((k, v), m)-{-# INLINE deleteFindMin #-}---- | /O(log n)/. Retrieves the value associated with maximal key of the--- map, and the map stripped of that element.------ Note that unlike @Data.IntMap.maxView@ from 'IntMap', this cannot ever fail,--- so doesn't need to return in a 'Maybe'. However, the result 'IntMap' is--- potentially empty, since the original map might have contained just--- a single item.------ > maxView (fromList ((5,"a") :| [(3,"b")])) == ("a", Data.IntMap.singleton 3 "b")-maxView :: NEIntMap a -> (a, IntMap a)-maxView = first snd . deleteFindMax-{-# INLINE maxView #-}---- | /O(log n)/. Delete and find the minimal key-value pair.------ Note that unlike @Data.IntMap.deleteFindMax@ for 'IntMap', this cannot ever--- fail, and so is a total function. However, the result 'IntMap' is--- potentially empty, since the original map might have contained just--- a single item.------ > deleteFindMax (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((10,"c"), Data.IntMap.fromList [(3,"b"), (5,"a")])-deleteFindMax :: NEIntMap a -> ((Key, a), IntMap a)-deleteFindMax (NEIntMap k v m) =- maybe ((k, v), M.empty) (second (insertMinMap k v))- . M.maxViewWithKey- $ m-{-# INLINE deleteFindMax #-}---- ------------------------------ Combining functions--- --------------------------------- Code comes from "Data.Map.Internal" from containers, modified slightly--- to work with NonEmpty------ Copyright : (c) Daan Leijen 2002--- (c) Andriy Palamarchuk 2008--combineEq :: NonEmpty (Key, b) -> NonEmpty (Key, b)-combineEq = \case- x :| [] -> x :| []- x :| xx@(_ : _) -> go x xx- where- go z [] = z :| []- go z@(kz, _) (x@(kx, xx) : xs')- | kx == kz = go (kx, xx) xs'- | otherwise = z NE.<| go x xs'--combineEqWith ::- (Key -> b -> b -> b) ->- NonEmpty (Key, b) ->- NonEmpty (Key, b)-combineEqWith f = \case- x :| [] -> x :| []- x :| xx@(_ : _) -> go x xx- where- go z [] = z :| []- go z@(kz, zz) (x@(kx, xx) : xs')- | kx == kz = let yy = f kx xx zz in go (kx, yy) xs'- | otherwise = z NE.<| go x xs'+-- |+-- Module : Data.IntMap.NonEmpty+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- = Non-Empty Finite Integer-Indexed Maps+--+-- This module re-exports "Data.IntMap.NonEmpty.Lazy". Import+-- "Data.IntMap.NonEmpty.Strict" for the strict value interface.+module Data.IntMap.NonEmpty (+ module Data.IntMap.NonEmpty.Lazy,+) where++import Data.IntMap.NonEmpty.Lazy
src/Data/IntMap/NonEmpty/Internal.hs view
@@ -1,9 +1,3 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ViewPatterns #-} {-# OPTIONS_HADDOCK not-home #-} -- |@@ -15,725 +9,11 @@ -- Stability : experimental -- Portability : non-portable ----- Unsafe internal-use functions used in the implementation of--- "Data.IntMap.NonEmpty". These functions can potentially be used to--- break the abstraction of 'NEIntMap' and produce unsound maps, so be--- wary!+-- Internal compatibility module for the lazy non-empty int map+-- implementation. Import "Data.IntMap.NonEmpty.Strict.Internal" for the+-- strict value variant. module Data.IntMap.NonEmpty.Internal (- -- * Non-Empty IntMap type- NEIntMap (..),- Key,- singleton,- nonEmptyMap,- withNonEmpty,- fromList,- toList,- map,- insertWith,- union,- unions,- elems,- size,- toMap,-- -- * Folds- foldr,- foldr',- foldr1,- foldl,- foldl',- foldl1,-- -- * Traversals- traverseWithKey,- traverseWithKey1,- foldMapWithKey,-- -- * Unsafe IntMap Functions- insertMinMap,- insertMaxMap,-- -- * Debug- valid,+ module Data.IntMap.NonEmpty.Lazy.Internal, ) where -import Control.Applicative-import Control.Comonad-import Control.DeepSeq-import Control.Monad-import qualified Data.Aeson as A-import Data.Coerce-import Data.Data-import qualified Data.Foldable as F-import Data.Foldable.WithIndex (FoldableWithIndex (..))-import Data.Function-import Data.Functor.Alt-import Data.Functor.Classes-import Data.Functor.Invariant-import Data.Functor.WithIndex (FunctorWithIndex (..))-import qualified Data.IntMap as M-import Data.IntMap.Internal (IntMap (..), Key)-import qualified Data.List as L-import Data.List.NonEmpty (NonEmpty (..))-import Data.Maybe-import Data.Semigroup-import Data.Semigroup.Foldable (Foldable1 (fold1))-import qualified Data.Semigroup.Foldable as F1-import Data.Semigroup.Traversable (Traversable1 (..))-import Data.Traversable.WithIndex (TraversableWithIndex (..))-import qualified GHC.Exts as Exts-import Text.Read-import Prelude hiding (Foldable (..), map)---- | A non-empty (by construction) map from integer keys to values @a@. At--- least one key-value pair exists in an @'NEIntMap' v@ at all times.------ Functions that /take/ an 'NEIntMap' can safely operate on it with the--- assumption that it has at least one key-value pair.------ Functions that /return/ an 'NEIntMap' provide an assurance that the result--- has at least one key-value pair.------ "Data.IntMap.NonEmpty" re-exports the API of "Data.IntMap", faithfully--- reproducing asymptotics, typeclass constraints, and semantics.--- Functions that ensure that input and output maps are both non-empty--- (like 'Data.IntMap.NonEmpty.insert') return 'NEIntMap', but functions that--- might potentially return an empty map (like 'Data.IntMap.NonEmpty.delete')--- return a 'IntMap' instead.------ You can directly construct an 'NEIntMap' with the API from--- "Data.IntMap.NonEmpty"; it's more or less the same as constructing a normal--- 'IntMap', except you don't have access to 'Data.IntMap.empty'. There are also--- a few ways to construct an 'NEIntMap' from a 'IntMap':------ 1. The 'nonEmptyMap' smart constructor will convert a @'IntMap' k a@ into--- a @'Maybe' ('NEIntMap' k a)@, returning 'Nothing' if the original 'IntMap'--- was empty.--- 2. You can use the 'Data.IntMap.NonEmpty.insertIntMap' family of functions to--- insert a value into a 'IntMap' to create a guaranteed 'NEIntMap'.--- 3. You can use the 'Data.IntMap.NonEmpty.IsNonEmpty' and--- 'Data.IntMap.NonEmpty.IsEmpty' patterns to "pattern match" on a 'IntMap'--- to reveal it as either containing a 'NEIntMap' or an empty map.--- 4. 'withNonEmpty' offers a continuation-based interface for--- deconstructing a 'IntMap' and treating it as if it were an--- 'NEIntMap'.------ You can convert an 'NEIntMap' into a 'IntMap' with 'toMap' or--- 'Data.IntMap.NonEmpty.IsNonEmpty', essentially "obscuring" the non-empty--- property from the type.-data NEIntMap a- = NEIntMap- { neimK0 :: !Key- -- ^ invariant: must be smaller than smallest key in map- , neimV0 :: a- , neimIntMap :: !(IntMap a)- }- deriving (Typeable)--instance Eq a => Eq (NEIntMap a) where- t1 == t2 =- M.size (neimIntMap t1) == M.size (neimIntMap t2)- && toList t1 == toList t2--instance Ord a => Ord (NEIntMap a) where- compare = compare `on` toList- (<) = (<) `on` toList- (>) = (>) `on` toList- (<=) = (<=) `on` toList- (>=) = (>=) `on` toList---- | @since 0.3.6.0-instance FunctorWithIndex Int NEIntMap where- imap f (NEIntMap k v m) = NEIntMap k (f k v) (M.mapWithKey f m)---- | @since 0.3.6.0-instance FoldableWithIndex Int NEIntMap where- ifoldMap = foldMapWithKey---- | @since 0.3.6.0-instance TraversableWithIndex Int NEIntMap where- itraverse f (NEIntMap k v m) =- NEIntMap k- <$> f k v- <*> M.traverseWithKey f m---- | @since 0.3.6.0-instance Exts.IsList (NEIntMap a) where- type Item (NEIntMap a) = (Key, a)-- fromList (a : as) = fromList (a :| as)- fromList [] = errorWithoutStackTrace "Data.IntMap.NonEmpty.fromList: empty list"-- toList = F.toList . toList--instance Eq1 NEIntMap where- liftEq eq m1 m2 =- M.size (neimIntMap m1) == M.size (neimIntMap m2)- && liftEq (liftEq eq) (toList m1) (toList m2)--instance Ord1 NEIntMap where- liftCompare cmp m n =- liftCompare (liftCompare cmp) (toList m) (toList n)--instance Show1 NEIntMap where- liftShowsPrec sp sl d m =- showsUnaryWith (liftShowsPrec sp' sl') "fromList" d (toList m)- where- sp' = liftShowsPrec sp sl- sl' = liftShowList sp sl--instance Read1 NEIntMap where- liftReadsPrec rp rl =- readsData $- readsUnaryWith (liftReadsPrec rp' rl') "fromList" fromList- where- rp' = liftReadsPrec rp rl- rl' = liftReadList rp rl--instance Read e => Read (NEIntMap e) where- readPrec = parens $ prec 10 $ do- Ident "fromList" <- lexP- xs <- parens . prec 10 $ readPrec- return (fromList xs)- readListPrec = readListPrecDefault--instance Show a => Show (NEIntMap a) where- showsPrec d m =- showParen (d > 10) $- showString "fromList (" . shows (toList m) . showString ")"--instance NFData a => NFData (NEIntMap a) where- rnf (NEIntMap k v a) = rnf k `seq` rnf v `seq` rnf a---- Data instance code from Data.IntMap.Internal------ Copyright : (c) Daan Leijen 2002--- (c) Andriy Palamarchuk 2008--- (c) wren romano 2016-#if MIN_VERSION_base(4,16,0)-instance Data a => Data (NEIntMap a) where- gfoldl f z im = z fromList `f` toList im- toConstr _ = fromListConstr- gunfold k z c = case constrIndex c of- 1 -> k (z fromList)- _ -> error "gunfold"- dataTypeOf _ = intMapDataType- dataCast1 = gcast1-#else-#ifndef __HLINT__-instance Data a => Data (NEIntMap a) where- gfoldl f z im = z fromList `f` toList im- toConstr _ = fromListConstr- gunfold k z c = case constrIndex c of- 1 -> k (z fromList)- _ -> error "gunfold"- dataTypeOf _ = intMapDataType- dataCast1 f = gcast1 f-#endif-#endif--fromListConstr :: Constr-fromListConstr = mkConstr intMapDataType "fromList" [] Prefix--intMapDataType :: DataType-intMapDataType = mkDataType "Data.IntMap.NonEmpty.Internal.NEIntMap" [fromListConstr]--instance A.ToJSON a => A.ToJSON (NEIntMap a) where- toJSON = A.toJSON . toMap- toEncoding = A.toEncoding . toMap--instance A.FromJSON a => A.FromJSON (NEIntMap a) where- parseJSON =- withNonEmpty (fail err) pure- <=< A.parseJSON- where- err = "NEIntMap: Non-empty map expected, but empty map found"---- | @since 0.3.4.4-instance Alt NEIntMap where- (<!>) = union---- | /O(n)/. Fold the values in the map using the given right-associative--- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'elems'@.------ > elemsList map = foldr (:) [] map------ > let f a len = len + (length a)--- > foldr f 0 (fromList ((5,"a") :| [(3,"bbb")])) == 4-foldr :: (a -> b -> b) -> b -> NEIntMap a -> b-foldr f z (NEIntMap _ v m) = v `f` M.foldr f z m-{-# INLINE foldr #-}---- | /O(n)/. A strict version of 'foldr'. Each application of the operator--- is evaluated before using the result in the next application. This--- function is strict in the starting value.-foldr' :: (a -> b -> b) -> b -> NEIntMap a -> b-foldr' f z (NEIntMap _ v m) = v `f` y- where- !y = M.foldr' f z m-{-# INLINE foldr' #-}---- | /O(n)/. A version of 'foldr' that uses the value at the maximal key in--- the map as the starting value.------ Note that, unlike 'Data.Foldable.foldr1' for 'IntMap', this function is--- total if the input function is total.-foldr1 :: (a -> a -> a) -> NEIntMap a -> a-foldr1 f (NEIntMap _ v m) =- maybe v (f v . uncurry (M.foldr f))- . M.maxView- $ m-{-# INLINE foldr1 #-}---- | /O(n)/. Fold the values in the map using the given left-associative--- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'elems'@.------ > elemsList = reverse . foldl (flip (:)) []------ > let f len a = len + (length a)--- > foldl f 0 (fromList ((5,"a") :| [(3,"bbb")])) == 4-foldl :: (a -> b -> a) -> a -> NEIntMap b -> a-foldl f z (NEIntMap _ v m) = M.foldl f (f z v) m-{-# INLINE foldl #-}---- | /O(n)/. A strict version of 'foldl'. Each application of the operator--- is evaluated before using the result in the next application. This--- function is strict in the starting value.-foldl' :: (a -> b -> a) -> a -> NEIntMap b -> a-foldl' f z (NEIntMap _ v m) = M.foldl' f x m- where- !x = f z v-{-# INLINE foldl' #-}---- | /O(n)/. A version of 'foldl' that uses the value at the minimal key in--- the map as the starting value.------ Note that, unlike 'Data.Foldable.foldl1' for 'IntMap', this function is--- total if the input function is total.-foldl1 :: (a -> a -> a) -> NEIntMap a -> a-foldl1 f (NEIntMap _ v m) = M.foldl f v m-{-# INLINE foldl1 #-}---- | /O(n)/. Fold the keys and values in the map using the given semigroup,--- such that------ @'foldMapWithKey' f = 'Data.Semigroup.Foldable.fold1' . 'Data.IntMap.NonEmpty.mapWithKey' f@------ __WARNING__: Differs from @Data.IntMap.foldMapWithKey@, which traverses--- positive items first, then negative items.------ This can be an asymptotically faster than--- 'Data.IntMap.NonEmpty.foldrWithKey' or 'Data.IntMap.NonEmpty.foldlWithKey' for--- some monoids.---- TODO: benchmark against maxView method-foldMapWithKey ::- Semigroup m =>- (Key -> a -> m) ->- NEIntMap a ->- m-foldMapWithKey f = F1.foldMap1 (uncurry f) . toList-{-# INLINE foldMapWithKey #-}---- | /O(n)/. IntMap a function over all values in the map.------ > map (++ "x") (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "bx") :| [(5, "ax")])-map :: (a -> b) -> NEIntMap a -> NEIntMap b-map f (NEIntMap k0 v m) = NEIntMap k0 (f v) (M.map f m)-{-# NOINLINE [1] map #-}--{-# RULES-"map/map" forall f g xs. map f (map g xs) = map (f . g) xs- #-}-{-# RULES-"map/coerce" map coerce = coerce- #-}---- | /O(m*log(n\/m + 1)), m <= n/.--- 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' == 'Data.IntMap.NonEmpty.unionWith' 'const'@).------ > union (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "a"), (7, "C")])-union ::- NEIntMap a ->- NEIntMap a ->- NEIntMap a-union n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of- LT -> NEIntMap k1 v1 . M.union m1 . toMap $ n2- EQ -> NEIntMap k1 v1 . M.union m1 $ m2- GT -> NEIntMap k2 v2 . M.union (toMap n1) $ m2-{-# INLINE union #-}---- | The left-biased union of a non-empty list of maps.------ > unions (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])--- > == fromList [(3, "b"), (5, "a"), (7, "C")]--- > unions (fromList ((5, "A3") :| [(3, "B3")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "a") :| [(3, "b")])])--- > == fromList ((3, "B3") :| [(5, "A3"), (7, "C")])-unions ::- Foldable1 f =>- f (NEIntMap a) ->- NEIntMap a-unions (F1.toNonEmpty -> (m :| ms)) = F.foldl' union m ms-{-# INLINE unions #-}---- | /O(n)/.--- Return all elements of the map in the ascending order of their keys.------ > elems (fromList ((5,"a") :| [(3,"b")])) == ("b" :| ["a"])-elems :: NEIntMap a -> NonEmpty a-elems (NEIntMap _ v m) = v :| M.elems m-{-# INLINE elems #-}---- | /O(1)/. The number of elements in the map. Guaranteed to be greater--- than zero.------ > size (singleton 1 'a') == 1--- > size (fromList ((1,'a') :| [(2,'c'), (3,'b')])) == 3-size :: NEIntMap a -> Int-size (NEIntMap _ _ m) = 1 + M.size m-{-# INLINE size #-}---- | /O(log n)/.--- Convert a non-empty map back into a normal possibly-empty map, for usage--- with functions that expect 'IntMap'.------ Can be thought of as "obscuring" the non-emptiness of the map in its--- type. See the 'Data.IntMap.NonEmpty.IsNotEmpty' pattern.------ 'nonEmptyMap' and @'maybe' 'Data.IntMap.empty' 'toMap'@ form an isomorphism: they--- are perfect structure-preserving inverses of eachother.------ > toMap (fromList ((3,"a") :| [(5,"b")])) == Data.IntMap.fromList [(3,"a"), (5,"b")]-toMap :: NEIntMap a -> IntMap a-toMap (NEIntMap k v m) = insertMinMap k v m-{-# INLINE toMap #-}---- | /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.------ /Use 'traverseWithKey1'/ whenever possible (if your 'Applicative'--- also has 'Apply' instance). This version is provided only for types--- that do not have 'Apply' instance, since 'Apply' is not at the moment--- (and might not ever be) an official superclass of 'Applicative'.------ __WARNING__: Differs from @Data.IntMap.traverseWithKey@, which traverses--- positive items first, then negative items.------ @--- 'traverseWithKey' f = 'unwrapApplicative' . 'traverseWithKey1' (\\k -> WrapApplicative . f k)--- @-traverseWithKey ::- Applicative t =>- (Key -> a -> t b) ->- NEIntMap a ->- t (NEIntMap b)-traverseWithKey f (NEIntMap k v m0) =- NEIntMap k- <$> f k v- <*> M.traverseWithKey f m0-{-# INLINE traverseWithKey #-}---- | /O(n)/.--- @'traverseWithKey1' f m == 'fromList' <$> 'traverse1' (\(k, v) -> (,) k <$> f k v) ('toList' m)@------ That is, behaves exactly like a regular 'traverse1' except that the traversing--- function also has access to the key associated with a value.------ __WARNING__: Differs from @Data.IntMap.traverseWithKey@, which traverses--- positive items first, then negative items.------ Is more general than 'traverseWithKey', since works with all 'Apply',--- and not just 'Applicative'.---- TODO: benchmark against maxView-based methods-traverseWithKey1 ::- Apply t =>- (Key -> a -> t b) ->- NEIntMap a ->- t (NEIntMap b)-traverseWithKey1 f (NEIntMap k0 v m0) = case runMaybeApply m1 of- Left m2 -> NEIntMap k0 <$> f k0 v <.> m2- Right m2 -> flip (NEIntMap k0) m2 <$> f k0 v- where- m1 = M.traverseWithKey (\k -> MaybeApply . Left . f k) m0-{-# INLINEABLE traverseWithKey1 #-}---- | /O(n)/. Convert the map to a non-empty list of key\/value pairs.------ > toList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])-toList :: NEIntMap a -> NonEmpty (Key, a)-toList (NEIntMap k v m) = (k, v) :| M.toList m-{-# INLINE toList #-}---- | /O(log n)/. Smart constructor for an 'NEIntMap' from a 'IntMap'. Returns--- 'Nothing' if the 'IntMap' was originally actually empty, and @'Just' n@--- with an 'NEIntMap', if the 'IntMap' was not empty.------ 'nonEmptyMap' and @'maybe' 'Data.IntMap.empty' 'toMap'@ form an--- isomorphism: they are perfect structure-preserving inverses of--- eachother.------ See 'Data.IntMap.NonEmpty.IsNonEmpty' for a pattern synonym that lets you--- "match on" the possiblity of a 'IntMap' being an 'NEIntMap'.------ > nonEmptyMap (Data.IntMap.fromList [(3,"a"), (5,"b")]) == Just (fromList ((3,"a") :| [(5,"b")]))-nonEmptyMap :: IntMap a -> Maybe (NEIntMap a)-nonEmptyMap = (fmap . uncurry . uncurry) NEIntMap . M.minViewWithKey-{-# INLINE nonEmptyMap #-}---- | /O(log n)/. A general continuation-based way to consume a 'IntMap' as if--- it were an 'NEIntMap'. @'withNonEmpty' def f@ will take a 'IntMap'. If map is--- empty, it will evaluate to @def@. Otherwise, a non-empty map 'NEIntMap'--- will be fed to the function @f@ instead.------ @'nonEmptyMap' == 'withNonEmpty' 'Nothing' 'Just'@-withNonEmpty ::- -- | value to return if map is empty- r ->- -- | function to apply if map is not empty- (NEIntMap a -> r) ->- IntMap a ->- r-withNonEmpty def f = maybe def f . nonEmptyMap-{-# INLINE withNonEmpty #-}---- | /O(n*log n)/. Build a non-empty map from a non-empty list of--- key\/value pairs. See also 'Data.IntMap.NonEmpty.fromAscList'. If the list--- contains more than one value for the same key, the last value for the--- key is retained.------ > fromList ((5,"a") :| [(3,"b"), (5, "c")]) == fromList ((5,"c") :| [(3,"b")])--- > fromList ((5,"c") :| [(3,"b"), (5, "a")]) == fromList ((5,"a") :| [(3,"b")])---- TODO: write manually and optimize to be equivalent to--- 'fromDistinctAscList' if items are ordered, just like the actual--- 'M.fromList'.-fromList :: NonEmpty (Key, a) -> NEIntMap a-fromList ((k, v) :| xs) =- withNonEmpty (singleton k v) (insertWith (const id) k v)- . M.fromList- $ xs-{-# INLINE fromList #-}---- | /O(1)/. A map with a single element.------ > singleton 1 'a' == fromList ((1, 'a') :| [])--- > size (singleton 1 'a') == 1-singleton :: Key -> a -> NEIntMap a-singleton k v = NEIntMap k v M.empty-{-# INLINE singleton #-}---- | /O(log n)/. Insert with a function, combining new value and old value.--- @'insertWith' f key value mp@ will insert the pair (key, value) into--- @mp@ if key does not exist in the map. If the key does exist, the--- function will insert the pair @(key, f new_value old_value)@.------ See 'Data.IntMap.NonEmpty.insertIntMapWith' for a version where the first--- argument is a 'IntMap'.------ > insertWith (++) 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "xxxa")])--- > insertWith (++) 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])-insertWith ::- (a -> a -> a) ->- Key ->- a ->- NEIntMap a ->- NEIntMap a-insertWith f k v n@(NEIntMap k0 v0 m) = case compare k k0 of- LT -> NEIntMap k v . toMap $ n- EQ -> NEIntMap k (f v v0) m- GT -> NEIntMap k0 v0 $ M.insertWith f k v m-{-# INLINE insertWith #-}---- | Left-biased union-instance Semigroup (NEIntMap a) where- (<>) = union- {-# INLINE (<>) #-}- sconcat = unions- {-# INLINE sconcat #-}--instance Functor NEIntMap where- fmap = map- {-# INLINE fmap #-}- x <$ NEIntMap k _ m = NEIntMap k x (x <$ m)- {-# INLINE (<$) #-}---- | @since 0.3.4.4-instance Invariant NEIntMap where- invmap f _ = fmap f- {-# INLINE invmap #-}---- | Traverses elements in order of ascending keys.------ __WARNING:__ 'F.fold' and 'F.foldMap' are different than for the--- 'IntMap' instance. They traverse elements in order of ascending keys,--- while 'IntMap' traverses positive keys first, then negative keys.------ 'Data.Foldable.foldr1', 'Data.Foldable.foldl1', 'Data.Foldable.minimum',--- 'Data.Foldable.maximum' are all total.-#if MIN_VERSION_base(4,11,0)-instance F.Foldable NEIntMap where- fold (NEIntMap _ v m) = v <> F.fold (M.elems m)- {-# INLINE fold #-}- foldMap f (NEIntMap _ v m) = f v <> F.foldMap f (M.elems m)- {-# INLINE foldMap #-}- foldr = foldr- {-# INLINE foldr #-}- foldr' = foldr'- {-# INLINE foldr' #-}- foldr1 = foldr1- {-# INLINE foldr1 #-}- foldl = foldl- {-# INLINE foldl #-}- foldl' = foldl'- {-# INLINE foldl' #-}- foldl1 = foldl1- {-# INLINE foldl1 #-}- null _ = False- {-# INLINE null #-}- length = size- {-# INLINE length #-}- elem x (NEIntMap _ v m) = F.elem x m- || x == v- {-# INLINE elem #-}- -- TODO: use build- toList = F.toList . elems- {-# INLINE toList #-}-#else-instance F.Foldable NEIntMap where- fold (NEIntMap _ v m) = v `mappend` F.fold (M.elems m)- {-# INLINE fold #-}- foldMap f (NEIntMap _ v m) = f v `mappend` F.foldMap f (M.elems m)- {-# INLINE foldMap #-}- foldr = foldr- {-# INLINE foldr #-}- foldr' = foldr'- {-# INLINE foldr' #-}- foldr1 = foldr1- {-# INLINE foldr1 #-}- foldl = foldl- {-# INLINE foldl #-}- foldl' = foldl'- {-# INLINE foldl' #-}- foldl1 = foldl1- {-# INLINE foldl1 #-}- null _ = False- {-# INLINE null #-}- length = size- {-# INLINE length #-}- elem x (NEIntMap _ v m) = F.elem x m- || x == v- {-# INLINE elem #-}- -- TODO: use build- toList = F.toList . elems- {-# INLINE toList #-}-#endif---- | Traverses elements in order of ascending keys------ __WARNING:__ Different than for the 'IntMap' instance. They traverse--- elements in order of ascending keys, while 'IntMap' traverses positive--- keys first, then negative keys.-instance Traversable NEIntMap where- traverse f = traverseWithKey (const f)- {-# INLINE traverse #-}---- | Traverses elements in order of ascending keys------ __WARNING:__ 'F1.fold1' and 'F1.foldMap1' are different than 'F.fold' and--- 'F.foldMap' for the 'IntMap' instance of 'Foldable'. They traverse--- elements in order of ascending keys, while 'IntMap' traverses positive--- keys first, then negative keys.-#if MIN_VERSION_base(4,11,0)-instance Foldable1 NEIntMap where- fold1 (NEIntMap _ v m) = maybe v (v <>)- . F.foldMap Just- . M.elems- $ m- {-# INLINE fold1 #-}- foldMap1 f = foldMapWithKey (const f)- {-# INLINE foldMap1 #-}- toNonEmpty = elems- {-# INLINE toNonEmpty #-}-#else-instance Foldable1 NEIntMap where- fold1 (NEIntMap _ v m) = option v (v <>)- . F.foldMap (Option . Just)- . M.elems- $ m- {-# INLINE fold1 #-}- foldMap1 f = foldMapWithKey (const f)- {-# INLINE foldMap1 #-}- toNonEmpty = elems- {-# INLINE toNonEmpty #-}-#endif---- | Traverses elements in order of ascending keys------ __WARNING:__ 'traverse1' and 'sequence1' are different 'traverse' and--- 'sequence' for the 'IntMap' instance of 'Traversable'. They traverse--- elements in order of ascending keys, while 'IntMap' traverses positive--- keys first, then negative keys.-instance Traversable1 NEIntMap where- traverse1 f = traverseWithKey1 (const f)- {-# INLINE traverse1 #-}---- | 'extract' gets the value at the minimal key, and 'duplicate' produces--- a map of maps comprised of all keys from the original map greater than--- or equal to the current key.------ @since 0.1.1.0-instance Comonad NEIntMap where- extract = neimV0- {-# INLINE extract #-}-- -- We'd like to use 'M.mapAccumWithKey', but it traverses things in the- -- wrong order.- duplicate n0@(NEIntMap k0 _ m0) =- NEIntMap k0 n0- . M.fromDistinctAscList- . snd- . L.mapAccumL go m0- . M.toList- $ m0- where- go m (k, v) = (m', (k, NEIntMap k v m'))- where- !m' = M.deleteMin m- {-# INLINE duplicate #-}---- | /O(n)/. Test if the internal map structure is valid.-valid :: NEIntMap a -> Bool-valid (NEIntMap k _ m) = all ((k <) . fst . fst) (M.minViewWithKey m)---- | /O(log n)/. Insert new key and value into a map where keys are--- /strictly greater than/ the new key. That is, the new key must be--- /strictly less than/ all keys present in the 'IntMap'. /The precondition--- is not checked./------ At the moment this is simply an alias for @Data.IntSet.insert@, but it's--- left here as a placeholder in case this eventually gets implemented in--- a more efficient way.---- TODO: implementation-insertMinMap :: Key -> a -> IntMap a -> IntMap a-insertMinMap = M.insert-{-# INLINEABLE insertMinMap #-}---- | /O(log n)/. Insert new key and value into a map where keys are--- /strictly less than/ the new key. That is, the new key must be--- /strictly greater than/ all keys present in the 'IntMap'. /The--- precondition is not checked./------ At the moment this is simply an alias for @Data.IntSet.insert@, but it's--- left here as a placeholder in case this eventually gets implemented in--- a more efficient way.---- TODO: implementation-insertMaxMap :: Key -> a -> IntMap a -> IntMap a-insertMaxMap = M.insert-{-# INLINEABLE insertMaxMap #-}+import Data.IntMap.NonEmpty.Lazy.Internal
+ src/Data/IntMap/NonEmpty/Lazy.hs view
@@ -0,0 +1,2072 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ViewPatterns #-}++-- |+-- Module : Data.IntMap.NonEmpty.Lazy+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- = Non-Empty Finite Integer-Indexed Maps (lazy interface)+--+-- The @'NEIntMap' v@ type represents a non-empty finite map (sometimes+-- called a dictionary) from integer keys to values of type @v@.+-- An 'NEIntMap' is strict in its keys but lazy in its values.+--+-- See documentation for 'NEIntMap' for information on how to convert and+-- manipulate such non-empty maps.+--+-- This module essentially re-imports the API of "Data.IntMap.Lazy" and its+-- 'IntMap' type, along with semantics and asymptotics. In most+-- situations, asymptotics are different only by a constant factor. In+-- some situations, asmyptotics are even better (constant-time instead of+-- log-time).+--+-- Because 'NEIntMap' is implemented using 'IntMap', all of the caveats of using+-- 'IntMap' apply (such as the limitation of the maximum size of maps).+--+-- All functions take non-empty maps as inputs. In situations where their+-- results can be guarunteed to also be non-empty, they also return+-- non-empty maps. In situations where their results could potentially be+-- empty, 'IntMap' is returned instead.+--+-- Some variants of functions (like 'alter'', 'alterF'', 'adjustMin',+-- 'adjustMax', 'adjustMinWithKey', 'adjustMaxWithKey') are provided in+-- a way restructured to preserve guaruntees of non-empty maps being+-- returned.+--+-- Some functions (like 'mapEither', 'partition', 'split')+-- have modified return types to account for possible configurations of+-- non-emptiness.+--+-- This module is intended to be imported qualified, to avoid name clashes with+-- "Prelude" and "Data.IntMap" functions:+--+-- > import qualified Data.IntMap.NonEmpty.Lazy as NEIM+--+-- Note that all asmyptotics /O(f(n))/ in this module are actually+-- /O(min(W, f(n)))/, where @W@ is the number of bits in an 'Int' (32 or+-- 64). That is, if @f(n)@ is greater than @W@, all operations are+-- constant-time.+--+-- Import "Data.IntMap.NonEmpty.Strict" for a variant strict on values.+module Data.IntMap.NonEmpty.Lazy (+ -- * Non-Empty IntMap Type+ NEIntMap,+ Key,++ -- ** Conversions between empty and non-empty maps+ pattern IsNonEmpty,+ pattern IsEmpty,+ nonEmptyMap,+ toMap,+ withNonEmpty,+ insertMap,+ insertMapWith,+ insertMapWithKey,+ insertMapMin,+ insertMapMax,+ unsafeFromMap,++ -- * Construction+ singleton,+ fromSet,++ -- ** From Unordered Lists+ fromList,+ fromListWith,+ fromListWithKey,++ -- ** From Ascending Lists+ fromAscList,+ fromAscListWith,+ fromAscListWithKey,+ fromDistinctAscList,++ -- * Insertion+ insert,+ insertWith,+ insertWithKey,+ insertLookupWithKey,++ -- * Deletion\/Update+ delete,+ deleteMaybe,+ adjust,+ adjustWithKey,+ update,+ updateWithKey,+ updateLookupWithKey,+ alter,+ alterF,+ alter',+ alterF',++ -- * Query++ -- ** Lookup+ lookup,+ (!?),+ (!),+ findWithDefault,+ member,+ notMember,+ lookupLT,+ lookupGT,+ lookupLE,+ lookupGE,++ -- ** Size+ size,++ -- * Combine++ -- ** Union+ union,+ unionMapLeft,+ unionMapRight,+ unionWith,+ unionMapWithLeft,+ unionMapWithRight,+ unionWithKey,+ unionMapWithKeyLeft,+ unionMapWithKeyRight,+ unions,+ unionsWith,++ -- ** Difference+ difference,+ (\\),+ differenceWith,+ differenceWithKey,++ -- ** Intersection+ intersection,+ intersectionWith,+ intersectionWithKey,+ -- -- ** Universal combining function+ -- , mergeWithKey++ -- * Traversal++ -- ** Map+ map,+ mapWithKey,+ traverseWithKey1,+ traverseWithKey,+ mapAccum,+ mapAccumWithKey,+ mapAccumRWithKey,+ mapKeys,+ mapKeysWith,+ mapKeysMonotonic,++ -- * Folds+ foldr,+ foldl,+ foldr1,+ foldl1,+ foldrWithKey,+ foldlWithKey,+ foldMapWithKey,++ -- ** Strict folds+ foldr',+ foldr1',+ foldl',+ foldl1',+ foldrWithKey',+ foldlWithKey',++ -- * Conversion+ elems,+ keys,+ assocs,+ keysSet,++ -- ** Lists+ toList,++ -- ** Ordered lists+ toAscList,+ toDescList,++ -- * Filter+ filter,+ filterWithKey,+ restrictKeys,+ withoutKeys,+ partition,+ partitionWithKey,+ mapMaybe,+ mapMaybeWithKey,+ mapEither,+ mapEitherWithKey,+ split,+ splitLookup,+ splitRoot,++ -- * Submap+ isSubmapOf,+ isSubmapOfBy,+ isProperSubmapOf,+ isProperSubmapOfBy,++ -- * Min\/Max+ findMin,+ findMax,+ deleteMin,+ deleteMax,+ deleteFindMin,+ deleteFindMax,+ updateMin,+ updateMax,+ adjustMin,+ adjustMax,+ updateMinWithKey,+ updateMaxWithKey,+ adjustMinWithKey,+ adjustMaxWithKey,+ minView,+ maxView,++ -- * Debugging+ valid,+) where++import Control.Applicative+import Data.Bifunctor+import qualified Data.Foldable as F+import Data.Functor.Identity+import qualified Data.IntMap as M+import Data.IntMap.Internal (IntMap (..))+import Data.IntMap.NonEmpty.Lazy.Internal+import Data.IntSet (IntSet)+import qualified Data.IntSet as S+import Data.IntSet.NonEmpty.Internal (NEIntSet (..))+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE+import Data.Maybe hiding (mapMaybe)+import qualified Data.Maybe as Maybe+import Data.Semigroup.Foldable (Foldable1)+import qualified Data.Semigroup.Foldable as F1+import Data.These+import Prelude hiding (Foldable (..), filter, lookup, map)++-- | /O(1)/ match, /O(log n)/ usage of contents. The 'IsNonEmpty' and+-- 'IsEmpty' patterns allow you to treat a 'IntMap' as if it were either+-- a @'IsNonEmpty' n@ (where @n@ is a 'NEIntMap') or an 'IsEmpty'.+--+-- For example, you can pattern match on a 'IntMap':+--+-- @+-- myFunc :: 'IntMap' K X -> Y+-- myFunc ('IsNonEmpty' n) = -- here, the user provided a non-empty map, and @n@ is the 'NEIntMap'+-- myFunc 'IsEmpty' = -- here, the user provided an empty map.+-- @+--+-- Matching on @'IsNonEmpty' n@ means that the original 'IntMap' was /not/+-- empty, and you have a verified-non-empty 'NEIntMap' @n@ to use.+--+-- Note that patching on this pattern is /O(1)/. However, using the+-- contents requires a /O(log n)/ cost that is deferred until after the+-- pattern is matched on (and is not incurred at all if the contents are+-- never used).+--+-- A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides+-- complete coverage.+--+-- This is a bidirectional pattern, so you can use 'IsNonEmpty' to convert+-- a 'NEIntMap' back into a 'IntMap', obscuring its non-emptiness (see 'toMap').+pattern IsNonEmpty :: NEIntMap a -> IntMap a+pattern IsNonEmpty n <- (nonEmptyMap -> Just n)+ where+ IsNonEmpty n = toMap n++-- | /O(1)/. The 'IsNonEmpty' and 'IsEmpty' patterns allow you to treat+-- a 'IntMap' as if it were either a @'IsNonEmpty' n@ (where @n@ is+-- a 'NEIntMap') or an 'IsEmpty'.+--+-- Matching on 'IsEmpty' means that the original 'IntMap' was empty.+--+-- A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides+-- complete coverage.+--+-- This is a bidirectional pattern, so you can use 'IsEmpty' as an+-- expression, and it will be interpreted as 'Data.IntMap.empty'.+--+-- See 'IsNonEmpty' for more information.+pattern IsEmpty :: IntMap a+pattern IsEmpty <- (M.null -> True)+ where+ IsEmpty = M.empty++{-# COMPLETE IsNonEmpty, IsEmpty #-}++-- | /O(log n)/. Unsafe version of 'nonEmptyMap'. Coerces a 'IntMap' into an+-- 'NEIntMap', but is undefined (throws a runtime exception when evaluation is+-- attempted) for an empty 'IntMap'.+unsafeFromMap ::+ IntMap a ->+ NEIntMap a+unsafeFromMap = withNonEmpty e id+ where+ e = errorWithoutStackTrace "NEIntMap.unsafeFromMap: empty map"+{-# INLINE unsafeFromMap #-}++-- | /O(log n)/. Convert a 'IntMap' into an 'NEIntMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. If key is already present,+-- will overwrite the original value.+--+-- See 'insertMapMin' for a version that is constant-time if the new key is+-- /strictly smaller than/ all keys in the original map.+--+-- > insertMap 4 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])+-- > insertMap 4 "c" Data.IntMap.empty == singleton 4 "c"+insertMap :: Key -> a -> IntMap a -> NEIntMap a+insertMap k v = withNonEmpty (singleton k v) (insert k v)+{-# INLINE insertMap #-}++-- | /O(log n)/. Convert a 'IntMap' into an 'NEIntMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. Uses a combining function+-- with the new value as the first argument if the key is already present.+--+-- > insertMapWith (++) 4 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])+-- > insertMapWith (++) 5 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"ca")])+insertMapWith ::+ (a -> a -> a) ->+ Key ->+ a ->+ IntMap a ->+ NEIntMap a+insertMapWith f k v = withNonEmpty (singleton k v) (insertWith f k v)+{-# INLINE insertMapWith #-}++-- | /O(log n)/. Convert a 'IntMap' into an 'NEIntMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. Uses a combining function+-- with the key and new value as the first and second arguments if the key+-- is already present.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "5:xxx|a")])+-- > insertWithKey f 7 "xxx" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+-- > insertWithKey f 5 "xxx" Data.IntMap.empty == singleton 5 "xxx"+insertMapWithKey ::+ (Key -> a -> a -> a) ->+ Key ->+ a ->+ IntMap a ->+ NEIntMap a+insertMapWithKey f k v = withNonEmpty (singleton k v) (insertWithKey f k v)+{-# INLINE insertMapWithKey #-}++-- | /O(1)/ Convert a 'IntMap' into an 'NEIntMap' by adding a key-value pair+-- where the key is /strictly less than/ all keys in the input map. The+-- keys in the original map must all be /strictly greater than/ the new+-- key. /The precondition is not checked./+--+-- > insertMapMin 2 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((2,"c") :| [(3,"b"), (5,"a")])+-- > valid (insertMapMin 2 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == True+-- > valid (insertMapMin 7 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False+-- > valid (insertMapMin 3 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False+insertMapMin ::+ Key ->+ a ->+ IntMap a ->+ NEIntMap a+insertMapMin = NEIntMap+{-# INLINE insertMapMin #-}++-- | /O(log n)/ Convert a 'IntMap' into an 'NEIntMap' by adding a key-value pair+-- where the key is /strictly greater than/ all keys in the input map. The+-- keys in the original map must all be /strictly less than/ the new+-- key. /The precondition is not checked./+--+-- At the current moment, this is identical simply 'insertMap'; however,+-- it is left both for consistency and as a placeholder for a future+-- version where optimizations are implemented to allow for a faster+-- implementation.+--+-- > insertMap 7 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"a"), (7,"c")])++-- these currently are all valid, but shouldn't be+-- > valid (insertMap 7 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == True+-- > valid (insertMap 2 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False+-- > valid (insertMap 5 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False+insertMapMax ::+ Key ->+ a ->+ IntMap a ->+ NEIntMap a+insertMapMax k v = withNonEmpty (singleton k v) go+ where+ go (NEIntMap k0 v0 m0) = NEIntMap k0 v0 . insertMaxMap k v $ m0+{-# INLINE insertMapMax #-}++-- | /O(n)/. Build a non-empty map from a non-empty set of keys and+-- a function which for each key computes its value.+--+-- > fromSet (\k -> replicate k 'a') (Data.Set.NonEmpty.fromList (3 :| [5])) == fromList ((5,"aaaaa") :| [(3,"aaa")])+fromSet ::+ (Key -> a) ->+ NEIntSet ->+ NEIntMap a+fromSet f (NEIntSet k ks) = NEIntMap k (f k) (M.fromSet f ks)+{-# INLINE fromSet #-}++-- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs+-- with a combining function. See also 'fromAscListWith'.+--+-- > fromListWith (++) ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "ab") :| [(5, "aba")])+fromListWith ::+ (a -> a -> a) ->+ NonEmpty (Key, a) ->+ NEIntMap a+fromListWith f = fromListWithKey (const f)+{-# INLINE fromListWith #-}++-- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs+-- with a combining function. See also 'fromAscListWithKey'.+--+-- > let f k a1 a2 = (show k) ++ a1 ++ a2+-- > fromListWithKey f ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "3ab") :| [(5, "5a5ba")])+fromListWithKey ::+ (Key -> a -> a -> a) ->+ NonEmpty (Key, a) ->+ NEIntMap a+fromListWithKey f ((k0, v0) :| xs) = F.foldl' go (singleton k0 v0) xs+ where+ go m (k, v) = insertWithKey f k v m+ {-# INLINE go #-}+{-# INLINE fromListWithKey #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time.+-- /The precondition (input list is ascending) is not checked./+--+-- > fromAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])+-- > fromAscList ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "b")])+-- > valid (fromAscList ((3,"b") :| [(5,"a"), (5,"b")])) == True+-- > valid (fromAscList ((5,"a") :| [(3,"b"), (5,"b")])) == False+fromAscList ::+ NonEmpty (Key, a) ->+ NEIntMap a+fromAscList = fromDistinctAscList . combineEq+{-# INLINE fromAscList #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is ascending) is not checked./+--+-- > fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "ba")])+-- > valid (fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b"))]) == True+-- > valid (fromAscListWith (++) ((5,"a") :| [(3,"b"), (5,"b"))]) == False+fromAscListWith ::+ (a -> a -> a) ->+ NonEmpty (Key, a) ->+ NEIntMap a+fromAscListWith f = fromAscListWithKey (const f)+{-# INLINE fromAscListWith #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is ascending) is not checked./+--+-- > let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2+-- > fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")]) == fromList ((3, "b") :| [(5, "5:b5:ba")])+-- > valid (fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")])) == True+-- > valid (fromAscListWithKey f ((5,"a") :| [(3,"b"), (5,"b"), (5,"b")])) == False+fromAscListWithKey ::+ (Key -> a -> a -> a) ->+ NonEmpty (Key, a) ->+ NEIntMap a+fromAscListWithKey f = fromDistinctAscList . combineEqWith f+{-# INLINE fromAscListWithKey #-}++-- | /O(n)/. Build a map from an ascending non-empty list of distinct+-- elements in linear time. /The precondition is not checked./+--+-- > fromDistinctAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])+-- > valid (fromDistinctAscList ((3,"b") :| [(5,"a")])) == True+-- > valid (fromDistinctAscList ((3,"b") :| [(5,"a"), (5,"b")])) == False+fromDistinctAscList :: NonEmpty (Key, a) -> NEIntMap a+fromDistinctAscList ((k, v) :| xs) =+ insertMapMin k v+ . M.fromDistinctAscList+ $ xs+{-# INLINE fromDistinctAscList #-}++-- | /O(log n)/. Insert a new key and value in the map.+-- If the key is already present in the map, the associated value is+-- replaced with the supplied value. 'insert' is equivalent to+-- @'insertWith' 'const'@.+--+-- See 'insertMap' for a version where the first argument is a 'IntMap'.+--+-- > insert 5 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'x')])+-- > insert 7 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'a'), (7, 'x')])+insert ::+ Key ->+ a ->+ NEIntMap a ->+ NEIntMap a+insert k v n@(NEIntMap k0 v0 m) = case compare k k0 of+ LT -> NEIntMap k v . toMap $ n+ EQ -> NEIntMap k v m+ GT -> NEIntMap k0 v0 . M.insert k v $ m+{-# INLINE insert #-}++-- | /O(log n)/. Insert with a function, combining key, new value and old+-- value. @'insertWithKey' f key value mp@ will insert the pair (key,+-- value) into @mp@ if key does not exist in the map. If the key does+-- exist, the function will insert the pair @(key,f key new_value+-- old_value)@. Note that the key passed to f is the same key passed to+-- 'insertWithKey'.+--+-- See 'insertMapWithKey' for a version where the first argument is a 'IntMap'.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:xxx|a")])+-- > insertWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+insertWithKey ::+ (Key -> a -> a -> a) ->+ Key ->+ a ->+ NEIntMap a ->+ NEIntMap a+insertWithKey f k v n@(NEIntMap k0 v0 m) = case compare k k0 of+ LT -> NEIntMap k v . toMap $ n+ EQ -> NEIntMap k (f k v v0) m+ GT -> NEIntMap k0 v0 $ M.insertWithKey f k v m+{-# INLINE insertWithKey #-}++-- | /O(log n)/. Combines insert operation with old value retrieval. The+-- expression (@'insertLookupWithKey' f k x map@) is a pair where the first+-- element is equal to (@'lookup' k map@) and the second element equal to+-- (@'insertWithKey' f k x map@).+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertLookupWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "5:xxx|a")]))+-- > insertLookupWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "xxx")]))+--+-- This is how to define @insertLookup@ using @insertLookupWithKey@:+--+-- > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t+-- > insertLookup 5 "x" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "x")]))+-- > insertLookup 7 "x" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "x")]))+insertLookupWithKey ::+ (Key -> a -> a -> a) ->+ Key ->+ a ->+ NEIntMap a ->+ (Maybe a, NEIntMap a)+insertLookupWithKey f k v n@(NEIntMap k0 v0 m) = case compare k k0 of+ LT -> (Nothing, NEIntMap k v . toMap $ n)+ EQ -> (Just v, NEIntMap k (f k v v0) m)+ GT -> NEIntMap k0 v0 <$> M.insertLookupWithKey f k v m+{-# INLINE insertLookupWithKey #-}++-- | /O(log n)/. Delete a key and its value from the non-empty map.+-- A potentially empty map ('IntMap') is returned, since this might delete the+-- last item in the 'NEIntMap'. When the key is not a member of the map, is+-- equivalent to 'toMap'.+--+-- > delete 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"+-- > delete 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.Singleton [(3, "b"), (5, "a")]+delete :: Key -> NEIntMap a -> IntMap a+delete k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> toMap n+ EQ -> m+ GT -> insertMinMap k0 v . M.delete k $ m+{-# INLINE delete #-}++-- | /O(log n)/. Delete a key and its value from the non-empty map, returning+-- 'Nothing' if the result would be empty.+--+-- This is more efficient than @'nonEmptyMap' . 'delete' k@ because it avoids+-- converting the known-minimum representation back through 'IntMap' when the+-- deleted key is not the minimum.+--+-- @since 0.3.6.0+deleteMaybe :: Key -> NEIntMap a -> Maybe (NEIntMap a)+deleteMaybe k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> Just n+ EQ -> nonEmptyMap m+ GT -> Just . NEIntMap k0 v . M.delete k $ m+{-# INLINE deleteMaybe #-}++-- | /O(log n)/. Update a value at a specific key with the result of the+-- provided function. When the key is not a member of the map, the original+-- map is returned.+--+-- > adjust ("new " ++) 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "new a")])+-- > adjust ("new " ++) 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])+adjust ::+ (a -> a) ->+ Key ->+ NEIntMap a ->+ NEIntMap a+adjust f = adjustWithKey (const f)+{-# INLINE adjust #-}++-- | /O(log n)/. Adjust a value at a specific key. When the key is not+-- a member of the map, the original map is returned.+--+-- > let f key x = (show key) ++ ":new " ++ x+-- > adjustWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:new a")])+-- > adjustWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])+adjustWithKey ::+ (Key -> a -> a) ->+ Key ->+ NEIntMap a ->+ NEIntMap a+adjustWithKey f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> n+ EQ -> NEIntMap k0 (f k0 v) m+ GT -> NEIntMap k0 v . M.adjustWithKey f k $ m+{-# INLINE adjustWithKey #-}++-- | /O(log n)/. The expression (@'update' f k map@) updates the value @x@+-- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is+-- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.+--+-- Returns a potentially empty map ('IntMap'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEIntMap'.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > update f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "new a")]+-- > update f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a")]+-- > update f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+update ::+ (a -> Maybe a) ->+ Key ->+ NEIntMap a ->+ IntMap a+update f = updateWithKey (const f)+{-# INLINE update #-}++-- | /O(log n)/. The expression (@'updateWithKey' f k map@) updates the+-- value @x@ at @k@ (if it is in the map). If (@f k x@) is 'Nothing',+-- the element is deleted. If it is (@'Just' y@), the key @k@ is bound+-- to the new value @y@.+--+-- Returns a potentially empty map ('IntMap'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEIntMap'.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "5:new a")]+-- > updateWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a")]+-- > updateWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+updateWithKey ::+ (Key -> a -> Maybe a) ->+ Key ->+ NEIntMap a ->+ IntMap a+updateWithKey f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> toMap n+ EQ -> maybe m (flip (insertMinMap k0) m) . f k0 $ v+ GT -> insertMinMap k0 v . M.updateWithKey f k $ m+{-# INLINE updateWithKey #-}++-- | /O(min(n,W))/. Lookup and update.+-- The function returns original value, if it is updated.+-- This is different behavior than @Data.Map.NonEmpty.updateLookupWithKey@.+-- Returns the original key value if the map entry is deleted.+--+-- Returns a potentially empty map ('IntMap') in the case that we delete+-- the final key of a singleton map.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateLookupWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == (Just "5:new a", Data.IntMap.fromList ((3, "b") :| [(5, "5:new a")]))+-- > updateLookupWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == (Nothing, Data.IntMap.fromList ((3, "b") :| [(5, "a")]))+-- > updateLookupWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == (Just "b", Data.IntMap.singleton 5 "a")+updateLookupWithKey ::+ (Key -> a -> Maybe a) ->+ Key ->+ NEIntMap a ->+ (Maybe a, IntMap a)+updateLookupWithKey f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> (Nothing, toMap n)+ EQ ->+ let u = f k0 v+ in (Just v, maybe m (flip (insertMinMap k0) m) u)+ GT -> fmap (insertMinMap k0 v) . M.updateLookupWithKey f k $ m+{-# INLINE updateLookupWithKey #-}++-- | /O(log n)/. The expression (@'alter' f k map@) alters the value @x@ at+-- @k@, or absence thereof. 'alter' can be used to insert, delete, or+-- update a value in a 'IntMap'. In short : @Data.IntMap.lookup k ('alter'+-- f k m) = f ('lookup' k m)@.+--+-- Returns a potentially empty map ('IntMap'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEIntMap'.+--+-- See 'alterF'' for a version that disallows deletion, and so therefore+-- can return 'NEIntMap'.+--+-- > let f _ = Nothing+-- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a")]+-- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"+-- >+-- > let f _ = Just "c"+-- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a"), (7, "c")]+-- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "c")]+alter ::+ (Maybe a -> Maybe a) ->+ Key ->+ NEIntMap a ->+ IntMap a+alter f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> maybe id (insertMinMap k) (f Nothing) (toMap n)+ EQ -> maybe id (insertMinMap k0) (f (Just v)) m+ GT -> insertMinMap k0 v . M.alter f k $ m+{-# INLINE alter #-}++-- | /O(log n)/. The expression (@'alterF' f k map@) alters the value @x@+-- at @k@, or absence thereof. 'alterF' can be used to inspect, insert,+-- delete, or update a value in a 'IntMap'. In short: @Data.IntMap.lookup+-- k \<$\> 'alterF' f k m = f ('lookup' k m)@.+--+-- Example:+--+-- @+-- interactiveAlter :: Int -> NEIntMap Int String -> IO (IntMap Int String)+-- interactiveAlter k m = alterF f k m where+-- f Nothing = do+-- putStrLn $ show k +++-- " was not found in the map. Would you like to add it?"+-- getUserResponse1 :: IO (Maybe String)+-- f (Just old) = do+-- putStrLn $ "The key is currently bound to " ++ show old +++-- ". Would you like to change or delete it?"+-- getUserResponse2 :: IO (Maybe String)+-- @+--+-- Like @Data.IntMap.alterF@ for 'IntMap', 'alterF' can be considered+-- to be a unifying generalization of 'lookup' and 'delete'; however, as+-- a constrast, it cannot be used to implement 'insert', because it must+-- return a 'IntMap' instead of an 'NEIntMap' (because the function might delete+-- the final item in the 'NEIntMap'). When used with trivial functors like+-- 'Identity' and 'Const', it is often slightly slower than+-- specialized 'lookup' and 'delete'. However, when the functor is+-- non-trivial and key comparison is not particularly cheap, it is the+-- fastest way.+--+-- See 'alterF'' for a version that disallows deletion, and so therefore+-- can return 'NEIntMap' and be used to implement 'insert'+--+-- Note on rewrite rules:+--+-- This module includes GHC rewrite rules to optimize 'alterF' for+-- the 'Const' and 'Identity' functors. In general, these rules+-- improve performance. The sole exception is that when using+-- 'Identity', deleting a key that is already absent takes longer+-- than it would without the rules. If you expect this to occur+-- a very large fraction of the time, you might consider using a+-- private copy of the 'Identity' type.+--+-- Note: Unlike @Data.IntMap.alterF@ for 'IntMap', 'alterF' is /not/ a flipped+-- version of the 'Control.Lens.At.at' combinator from "Control.Lens.At".+-- However, it match the shape expected from most functions expecting+-- lenses, getters, and setters, so can be thought of as a "psuedo-lens",+-- with virtually the same practical applications as a legitimate lens.+alterF ::+ Functor f =>+ (Maybe a -> f (Maybe a)) ->+ Key ->+ NEIntMap a ->+ f (IntMap a)+alterF f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> flip (maybe id (insertMinMap k)) (toMap n) <$> f Nothing+ EQ -> flip (maybe id (insertMinMap k0)) m <$> f (Just v)+ GT -> insertMinMap k0 v <$> M.alterF f k m+{-# INLINEABLE [2] alterF #-}++-- if f ~ Const b, it's a lookup+{-# RULES+"alterF/Const" forall k (f :: Maybe a -> Const b (Maybe a)).+ alterF f k =+ Const . getConst . f . lookup k+ #-}++-- if f ~ Identity, it's an 'alter'+{-# RULES+"alterF/Identity" forall k (f :: Maybe a -> Identity (Maybe a)).+ alterF f k =+ Identity . alter (runIdentity . f) k+ #-}++-- | /O(log n)/. Variant of 'alter' that disallows deletion. Allows us to+-- guarantee that the result is also a non-empty IntMap.+alter' ::+ (Maybe a -> a) ->+ Key ->+ NEIntMap a ->+ NEIntMap a+alter' f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> NEIntMap k (f Nothing) . toMap $ n+ EQ -> NEIntMap k0 (f (Just v)) m+ GT -> NEIntMap k0 v . M.alter (Just . f) k $ m+{-# INLINE alter' #-}++-- | /O(log n)/. Variant of 'alterF' that disallows deletion. Allows us to+-- guarantee that the result is also a non-empty IntMap.+--+-- Like @Data.IntMap.alterF@ for 'IntMap', can be used to generalize and unify+-- 'lookup' and 'insert'. However, because it disallows deletion, it+-- cannot be used to implement 'delete'.+--+-- See 'alterF' for usage information and caveats.+--+-- Note: Neither 'alterF' nor 'alterF'' can be considered flipped versions+-- of the 'Control.Lens.At.at' combinator from "Control.Lens.At". However,+-- this can match the shape expected from most functions expecting lenses,+-- getters, and setters, so can be thought of as a "psuedo-lens", with+-- virtually the same practical applications as a legitimate lens.+--+-- __WARNING__: The rewrite rule for 'Identity' exposes an inconsistency in+-- undefined behavior for "Data.IntMap". @Data.IntMap.alterF@ will actually+-- /maintain/ the original key in the map when used with 'Identity';+-- however, @Data.IntMap.insertWith@ will /replace/ the orginal key in the+-- map. The rewrite rule for 'alterF'' has chosen to be faithful to+-- @Data.IntMap.insertWith@, and /not/ @Data.IntMap.alterF@, for the sake of+-- a cleaner implementation.+alterF' ::+ Functor f =>+ (Maybe a -> f a) ->+ Key ->+ NEIntMap a ->+ f (NEIntMap a)+alterF' f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> flip (NEIntMap k) (toMap n) <$> f Nothing+ EQ -> flip (NEIntMap k0) m <$> f (Just v)+ GT -> NEIntMap k0 v <$> M.alterF (fmap Just . f) k m+{-# INLINEABLE [2] alterF' #-}++-- if f ~ Const b, it's a lookup+{-# RULES+"alterF'/Const" forall k (f :: Maybe a -> Const b a).+ alterF' f k =+ Const . getConst . f . lookup k+ #-}++-- if f ~ Identity, it's an insertWith+{-# RULES+"alterF'/Identity" forall k (f :: Maybe a -> Identity a).+ alterF' f k =+ Identity . insertWith (\_ -> runIdentity . f . Just) k (runIdentity (f Nothing))+ #-}++-- | /O(log n)/. Lookup the value at a key in the map.+--+-- The function will return the corresponding value as @('Just' value)@,+-- or 'Nothing' if the key isn't in the map.+--+-- An example of using @lookup@:+--+-- > import Prelude hiding (lookup)+-- > import Data.Map.NonEmpty+-- >+-- > employeeDept = fromList (("John","Sales") :| [("Bob","IT")])+-- > deptCountry = fromList (("IT","USA") :| [("Sales","France")])+-- > countryCurrency = fromList (("USA", "Dollar") :| [("France", "Euro")])+-- >+-- > employeeCurrency :: String -> Maybe String+-- > employeeCurrency name = do+-- > dept <- lookup name employeeDept+-- > country <- lookup dept deptCountry+-- > lookup country countryCurrency+-- >+-- > main = do+-- > putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))+-- > putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))+--+-- The output of this program:+--+-- > John's currency: Just "Euro"+-- > Pete's currency: Nothing+lookup ::+ Key ->+ NEIntMap a ->+ Maybe a+lookup k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just v+ GT -> M.lookup k m+{-# INLINE lookup #-}++-- | /O(log n)/. Find the value at a key. Returns 'Nothing' when the+-- element can not be found.+--+-- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 1 == Nothing+-- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 5 == Just 'a'+(!?) :: NEIntMap a -> Key -> Maybe a+(!?) = flip lookup+{-# INLINE (!?) #-}++-- | /O(log n)/. Find the value at a key. Calls 'error' when the element+-- can not be found.+--+-- > fromList ((5,'a') :| [(3,'b')]) ! 1 Error: element not in the map+-- > fromList ((5,'a') :| [(3,'b')]) ! 5 == 'a'+(!) :: NEIntMap a -> Key -> a+(!) m k = fromMaybe e $ m !? k+ where+ e = error "NEIntMap.!: given key is not an element in the map"+{-# INLINE (!) #-}++infixl 9 !?+infixl 9 !++-- | /O(log n)/. The expression @('findWithDefault' def k map)@ returns+-- the value at key @k@ or returns default value @def@+-- when the key is not in the map.+--+-- > findWithDefault 'x' 1 (fromList ((5,'a') :| [(3,'b')])) == 'x'+-- > findWithDefault 'x' 5 (fromList ((5,'a') :| [(3,'b')])) == 'a'+findWithDefault ::+ a ->+ Key ->+ NEIntMap a ->+ a+findWithDefault def k (NEIntMap k0 v m) = case compare k k0 of+ LT -> def+ EQ -> v+ GT -> M.findWithDefault def k m+{-# INLINE findWithDefault #-}++-- | /O(log n)/. Is the key a member of the map? See also 'notMember'.+--+-- > member 5 (fromList ((5,'a') :| [(3,'b')])) == True+-- > member 1 (fromList ((5,'a') :| [(3,'b')])) == False+member :: Key -> NEIntMap a -> Bool+member k (NEIntMap k0 _ m) = case compare k k0 of+ LT -> False+ EQ -> True+ GT -> M.member k m+{-# INLINE member #-}++-- | /O(log n)/. Is the key not a member of the map? See also 'member'.+--+-- > notMember 5 (fromList ((5,'a') :| [(3,'b')])) == False+-- > notMember 1 (fromList ((5,'a') :| [(3,'b')])) == True+notMember :: Key -> NEIntMap a -> Bool+notMember k (NEIntMap k0 _ m) = case compare k k0 of+ LT -> True+ EQ -> False+ GT -> M.notMember k m+{-# INLINE notMember #-}++-- | /O(log n)/. Find largest key smaller than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupLT 3 (fromList ((3,'a') :| [(5,'b')])) == Nothing+-- > lookupLT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+lookupLT :: Key -> NEIntMap a -> Maybe (Key, a)+lookupLT k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Nothing+ GT -> M.lookupLT k m <|> Just (k0, v)+{-# INLINE lookupLT #-}++-- | /O(log n)/. Find smallest key greater than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupGT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+-- > lookupGT 5 (fromList ((3,'a') :| [(5,'b')])) == Nothing+lookupGT :: Key -> NEIntMap a -> Maybe (Key, a)+lookupGT k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Just (k0, v)+ EQ -> M.lookupMin m+ GT -> M.lookupGT k m+{-# INLINE lookupGT #-}++-- | /O(log n)/. Find largest key smaller or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupLE 2 (fromList ((3,'a') :| [(5,'b')])) == Nothing+-- > lookupLE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+-- > lookupLE 5 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+lookupLE :: Key -> NEIntMap a -> Maybe (Key, a)+lookupLE k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just (k0, v)+ GT -> M.lookupLE k m <|> Just (k0, v)+{-# INLINE lookupLE #-}++-- | /O(log n)/. Find smallest key greater or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupGE 3 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+-- > lookupGE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+-- > lookupGE 6 (fromList ((3,'a') :| [(5,'b')])) == Nothing+lookupGE :: Key -> NEIntMap a -> Maybe (Key, a)+lookupGE k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Just (k0, v)+ EQ -> Just (k0, v)+ GT -> M.lookupGE k m+{-# INLINE lookupGE #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union with a combining function.+--+-- > unionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "aA"), (7, "C")])+unionWith ::+ (a -> a -> a) ->+ NEIntMap a ->+ NEIntMap a ->+ NEIntMap a+unionWith f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEIntMap k1 v1 . M.unionWith f m1 . toMap $ n2+ EQ -> NEIntMap k1 (f v1 v2) . M.unionWith f m1 $ m2+ GT -> NEIntMap k2 v2 . M.unionWith f (toMap n1) $ m2+{-# INLINE unionWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a possibly-empty+-- 'IntMap' and a non-empty map.+--+-- @since 0.3.6.0+unionMapLeft :: IntMap a -> NEIntMap a -> NEIntMap a+unionMapLeft m n = withNonEmpty n (`union` n) m+{-# INLINE unionMapLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a non-empty map and a+-- possibly-empty 'IntMap'.+--+-- @since 0.3.6.0+unionMapRight :: NEIntMap a -> IntMap a -> NEIntMap a+unionMapRight n = withNonEmpty n (union n)+{-# INLINE unionMapRight #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'IntMap' and a+-- non-empty map with a combining function.+--+-- @since 0.3.6.0+unionMapWithLeft :: (a -> a -> a) -> IntMap a -> NEIntMap a -> NEIntMap a+unionMapWithLeft f m n = withNonEmpty n (\m' -> unionWith f m' n) m+{-# INLINE unionMapWithLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a+-- possibly-empty 'IntMap' with a combining function.+--+-- @since 0.3.6.0+unionMapWithRight :: (a -> a -> a) -> NEIntMap a -> IntMap a -> NEIntMap a+unionMapWithRight f n = withNonEmpty n (unionWith f n)+{-# INLINE unionMapWithRight #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- Union with a combining function, given the matching key.+--+-- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value+-- > unionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "5:a|A"), (7, "C")])+unionWithKey ::+ (Key -> a -> a -> a) ->+ NEIntMap a ->+ NEIntMap a ->+ NEIntMap a+unionWithKey f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEIntMap k1 v1 . M.unionWithKey f m1 . toMap $ n2+ EQ -> NEIntMap k1 (f k1 v1 v2) . M.unionWithKey f m1 $ m2+ GT -> NEIntMap k2 v2 . M.unionWithKey f (toMap n1) $ m2+{-# INLINE unionWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'IntMap' and a+-- non-empty map with a combining function, given the matching key.+--+-- @since 0.3.6.0+unionMapWithKeyLeft ::+ (Key -> a -> a -> a) ->+ IntMap a ->+ NEIntMap a ->+ NEIntMap a+unionMapWithKeyLeft f m n = withNonEmpty n (\m' -> unionWithKey f m' n) m+{-# INLINE unionMapWithKeyLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a+-- possibly-empty 'IntMap' with a combining function, given the matching key.+--+-- @since 0.3.6.0+unionMapWithKeyRight ::+ (Key -> a -> a -> a) ->+ NEIntMap a ->+ IntMap a ->+ NEIntMap a+unionMapWithKeyRight f n = withNonEmpty n (unionWithKey f n)+{-# INLINE unionMapWithKeyRight #-}++-- | The union of a non-empty list of maps, with a combining operation:+-- (@'unionsWith' f == 'Data.Foldable.foldl1' ('unionWith' f)@).+--+-- > unionsWith (++) (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])+-- > == fromList ((3, "bB3") :| [(5, "aAA3"), (7, "C")])+unionsWith ::+ Foldable1 f =>+ (a -> a -> a) ->+ f (NEIntMap a) ->+ NEIntMap a+unionsWith f (F1.toNonEmpty -> (m :| ms)) = F.foldl' (unionWith f) m ms+{-# INLINE unionsWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Difference of two maps.+-- Return elements of the first map not existing in the second map.+--+-- Returns a potentially empty map ('IntMap'), in case the first map is+-- a subset of the second map.+--+-- > difference (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 3 "b"+difference ::+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+difference n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 _ m2) = case compare k1 k2 of+ -- k1 is not in n2, so cannot be deleted+ LT -> insertMinMap k1 v1 $ m1 `M.difference` toMap n2+ -- k2 deletes k1, and only k1+ EQ -> m1 `M.difference` m2+ -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.+ GT -> toMap n1 `M.difference` m2+{-# INLINE difference #-}++-- | Same as 'difference'.+(\\) ::+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+(\\) = difference+{-# INLINE (\\) #-}++-- | /O(n+m)/. Difference with a combining function.+-- When two equal keys are+-- encountered, the combining function is applied to the values of these keys.+-- 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@.+--+-- Returns a potentially empty map ('IntMap'), in case the first map is+-- a subset of the second map and the function returns 'Nothing' for every+-- pair.+--+-- > let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing+-- > differenceWith f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (7, "C")]))+-- > == Data.IntMap.singleton 3 "b:B"+differenceWith ::+ (a -> b -> Maybe a) ->+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+differenceWith f = differenceWithKey (const f)+{-# INLINE differenceWith #-}++-- | /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@.+--+-- Returns a potentially empty map ('IntMap'), in case the first map is+-- a subset of the second map and the function returns 'Nothing' for every+-- pair.+--+-- > let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing+-- > differenceWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (10, "C")]))+-- > == Data.IntMap.singleton 3 "3:b|B"+differenceWithKey ::+ (Key -> a -> b -> Maybe a) ->+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+differenceWithKey f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ -- k1 is not in n2, so cannot be deleted+ LT -> insertMinMap k1 v1 $ M.differenceWithKey f m1 (toMap n2)+ -- k2 deletes k1, and only k1+ EQ -> maybe id (insertMinMap k1) (f k1 v1 v2) (M.differenceWithKey f m1 m2)+ -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.+ GT -> M.differenceWithKey f (toMap n1) m2+{-# INLINE differenceWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection of two maps.+-- Return data in the first map for the keys existing in both maps.+-- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).+--+-- Returns a potentially empty map ('IntMap'), in case the two maps share no+-- keys in common.+--+-- > intersection (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 5 "a"+intersection ::+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+intersection n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 _ m2) = case compare k1 k2 of+ -- k1 is not in n2+ LT -> m1 `M.intersection` toMap n2+ -- k1 and k2 are a part of the result+ EQ -> insertMinMap k1 v1 $ m1 `M.intersection` m2+ -- k2 is not in n1+ GT -> toMap n1 `M.intersection` m2+{-# INLINE intersection #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.+--+-- Returns a potentially empty map ('IntMap'), in case the two maps share no+-- keys in common.+--+-- > intersectionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 5 "aA"+intersectionWith ::+ (a -> b -> c) ->+ NEIntMap a ->+ NEIntMap b ->+ IntMap c+intersectionWith f = intersectionWithKey (const f)+{-# INLINE intersectionWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.+--+-- Returns a potentially empty map ('IntMap'), in case the two maps share no+-- keys in common.+--+-- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar+-- > intersectionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 5 "5:a|A"+intersectionWithKey ::+ (Key -> a -> b -> c) ->+ NEIntMap a ->+ NEIntMap b ->+ IntMap c+intersectionWithKey f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ -- k1 is not in n2+ LT -> M.intersectionWithKey f m1 (toMap n2)+ -- k1 and k2 are a part of the result+ EQ -> insertMinMap k1 (f k1 v1 v2) $ M.intersectionWithKey f m1 m2+ -- k2 is not in n1+ GT -> M.intersectionWithKey f (toMap n1) m2+{-# INLINE intersectionWithKey #-}++-- | /O(n)/. IntMap a function over all values in the map.+--+-- > let f key x = (show key) ++ ":" ++ x+-- > mapWithKey f (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "3:b") :| [(5, "5:a")])+mapWithKey :: (Key -> a -> b) -> NEIntMap a -> NEIntMap b+mapWithKey f (NEIntMap k v m) = NEIntMap k (f k v) (M.mapWithKey f m)+{-# NOINLINE [1] mapWithKey #-}++{-# RULES+"mapWithKey/mapWithKey" forall f g xs.+ mapWithKey f (mapWithKey g xs) =+ mapWithKey (\k a -> f k (g k a)) xs+"mapWithKey/map" forall f g xs.+ mapWithKey f (map g xs) =+ mapWithKey (\k a -> f k (g a)) xs+"map/mapWithKey" forall f g xs.+ map f (mapWithKey g xs) =+ mapWithKey (\k a -> f (g k a)) xs+ #-}++-- | /O(n)/. The function 'mapAccum' threads an accumulating argument+-- through the map in ascending order of keys.+--+-- > let f a b = (a ++ b, b ++ "X")+-- > mapAccum f "Everything: " (fromList ((5,"a") :| [(3,"b")])) == ("Everything: ba", fromList ((3, "bX") :| [(5, "aX")]))+mapAccum ::+ (a -> b -> (a, c)) ->+ a ->+ NEIntMap b ->+ (a, NEIntMap c)+mapAccum f = mapAccumWithKey (\x _ -> f x)+{-# INLINE mapAccum #-}++-- | /O(n)/. The function 'mapAccumWithKey' threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")+-- > mapAccumWithKey f "Everything:" (fromList ((5,"a") :| [(3,"b")])) == ("Everything: 3-b 5-a", fromList ((3, "bX") :| [(5, "aX")]))+mapAccumWithKey ::+ (a -> Key -> b -> (a, c)) ->+ a ->+ NEIntMap b ->+ (a, NEIntMap c)+mapAccumWithKey f z0 (NEIntMap k v m) = (z2, NEIntMap k v' m')+ where+ ~(z1, v') = f z0 k v+ ~(z2, m') = M.mapAccumWithKey f z1 m+{-# INLINE mapAccumWithKey #-}++-- | /O(n)/. The function 'mapAccumRWithKey' threads an accumulating+-- argument through the map in descending order of keys.+mapAccumRWithKey ::+ (a -> Key -> b -> (a, c)) ->+ a ->+ NEIntMap b ->+ (a, NEIntMap c)+mapAccumRWithKey f z0 (NEIntMap k v m) = (z2, NEIntMap k v' m')+ where+ ~(z1, m') = M.mapAccumRWithKey f z0 m+ ~(z2, v') = f z1 k v+{-# INLINE mapAccumRWithKey #-}++-- | /O(n*log n)/.+-- @'mapKeys' 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 value at the greatest of the+-- original keys is retained.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeys (+ 1) (fromList ((5,"a") :| [(3,"b")])) == fromList ((4, "b") :| [(6, "a")])+-- > mapKeys (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "c"+-- > mapKeys (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "c"+mapKeys ::+ (Key -> Key) ->+ NEIntMap a ->+ NEIntMap a+mapKeys f (NEIntMap k0 v0 m) =+ fromListWith const+ . ((f k0, v0) :|)+ . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []+ $ m+{-# INLINEABLE mapKeys #-}++-- | /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@. The value at the greater of the two original keys+-- is used as the first argument to @c@.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeysWith (++) (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "cdab"+-- > mapKeysWith (++) (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "cdab"+mapKeysWith ::+ (a -> a -> a) ->+ (Key -> Key) ->+ NEIntMap a ->+ NEIntMap a+mapKeysWith c f (NEIntMap k0 v0 m) =+ fromListWith c+ . ((f k0, v0) :|)+ . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []+ $ m+{-# INLINEABLE mapKeysWith #-}++-- | /O(n)/.+-- @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@+-- is strictly monotonic.+-- 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]+-- > ==> mapKeysMonotonic f s == mapKeys f s+-- > where ls = keys s+--+-- This means that @f@ maps distinct original keys to distinct resulting keys.+-- This function has better performance than 'mapKeys'.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")])) == fromList ((6, "b") :| [(10, "a")])+-- > valid (mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")]))) == True+-- > valid (mapKeysMonotonic (\ _ -> 1) (fromList ((5,"a") :| [(3,"b")]))) == False+mapKeysMonotonic ::+ (Key -> Key) ->+ NEIntMap a ->+ NEIntMap a+mapKeysMonotonic f (NEIntMap k v m) =+ NEIntMap (f k) v+ . M.mapKeysMonotonic f+ $ m+{-# INLINE mapKeysMonotonic #-}++-- | /O(n)/. Fold the keys and values in the map using the given right-associative+-- binary operator, such that+-- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.+--+-- For example,+--+-- > keysList map = foldrWithKey (\k x ks -> k:ks) [] map+foldrWithKey :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b+foldrWithKey f z (NEIntMap k v m) = f k v . M.foldrWithKey f z $ m+{-# INLINE foldrWithKey #-}++-- | /O(n)/. Fold the keys and values in the map using the given left-associative+-- binary operator, such that+-- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.+--+-- For example,+--+-- > keysList = reverse . foldlWithKey (\ks k x -> k:ks) []+foldlWithKey :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a+foldlWithKey f z (NEIntMap k v m) = M.foldlWithKey f (f z k v) m+{-# INLINE foldlWithKey #-}++-- | /O(n)/. A strict version of 'foldr1'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldr1' :: (a -> a -> a) -> NEIntMap a -> a+foldr1' f (NEIntMap _ v m) = case M.maxView m of+ Nothing -> v+ Just (y, m') -> let !z = M.foldr' f y m' in v `f` z+{-# INLINE foldr1' #-}++-- | /O(n)/. A strict version of 'foldl1'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldl1' :: (a -> a -> a) -> NEIntMap a -> a+foldl1' f (NEIntMap _ v m) = M.foldl' f v m+{-# INLINE foldl1' #-}++-- | /O(n)/. A strict version of 'foldrWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldrWithKey' :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b+foldrWithKey' f z (NEIntMap k v m) = f k v y+ where+ !y = M.foldrWithKey f z m+{-# INLINE foldrWithKey' #-}++-- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldlWithKey' :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a+foldlWithKey' f z (NEIntMap k v m) = M.foldlWithKey' f x m+ where+ !x = f z k v+{-# INLINE foldlWithKey' #-}++-- | /O(n)/. Return all keys of the map in ascending order.+--+-- > keys (fromList ((5,"a") :| [(3,"b")])) == (3 :| [5])+keys :: NEIntMap a -> NonEmpty Key+keys (NEIntMap k _ m) = k :| M.keys m+{-# INLINE keys #-}++-- | /O(n)/. An alias for 'toAscList'. Return all key\/value pairs in the map+-- in ascending key order.+--+-- > assocs (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+assocs :: NEIntMap a -> NonEmpty (Key, a)+assocs = toList+{-# INLINE assocs #-}++-- | /O(n)/. The non-empty set of all keys of the map.+--+-- > keysSet (fromList ((5,"a") :| [(3,"b")])) == Data.Set.NonEmpty.fromList (3 :| [5])+keysSet :: NEIntMap a -> NEIntSet+keysSet (NEIntMap k _ m) = NEIntSet k (M.keysSet m)+{-# INLINE keysSet #-}++-- | /O(n)/. Convert the map to a list of key\/value pairs where the keys are+-- in ascending order.+--+-- > toAscList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+toAscList :: NEIntMap a -> NonEmpty (Key, a)+toAscList = toList+{-# INLINE toAscList #-}++-- | /O(n)/. Convert the map to a list of key\/value pairs where the keys+-- are in descending order.+--+-- > toDescList (fromList ((5,"a") :| [(3,"b")])) == ((5,"a") :| [(3,"b")])+toDescList :: NEIntMap a -> NonEmpty (Key, a)+toDescList (NEIntMap k0 v0 m) = M.foldlWithKey' go ((k0, v0) :| []) m+ where+ go xs k v = (k, v) NE.<| xs+{-# INLINE toDescList #-}++-- | /O(n)/. Filter all values that satisfy the predicate.+--+-- Returns a potentially empty map ('IntMap'), because we could+-- potentailly filter out all items in the original 'NEIntMap'.+--+-- > filter (> "a") (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"+-- > filter (> "x") (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.empty+-- > filter (< "a") (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.empty+filter ::+ (a -> Bool) ->+ NEIntMap a ->+ IntMap a+filter f (NEIntMap k v m)+ | f v = insertMinMap k v . M.filter f $ m+ | otherwise = M.filter f m+{-# INLINE filter #-}++-- | /O(n)/. Filter all keys\/values that satisfy the predicate.+--+-- Returns a potentially empty map ('IntMap'), because we could+-- potentailly filter out all items in the original 'NEIntMap'.+--+-- > filterWithKey (\k _ -> k > 4) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+filterWithKey ::+ (Key -> a -> Bool) ->+ NEIntMap a ->+ IntMap a+filterWithKey f (NEIntMap k v m)+ | f k v = insertMinMap k v . M.filterWithKey f $ m+ | otherwise = M.filterWithKey f m+{-# INLINE filterWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Restrict an 'NEIntMap' to only those keys+-- found in a 'Data.Set.Set'.+--+-- @+-- m \`restrictKeys\` s = 'filterWithKey' (\k _ -> k ``Set.member`` s) m+-- m \`restrictKeys\` s = m ``intersection`` 'fromSet' (const ()) s+-- @+restrictKeys ::+ NEIntMap a ->+ IntSet ->+ IntMap a+restrictKeys n@(NEIntMap k v m) xs = case S.minView xs of+ Nothing -> M.empty+ Just (y, ys) -> case compare k y of+ -- k is not in xs+ LT -> m `M.restrictKeys` xs+ -- k and y are a part of the result+ EQ -> insertMinMap k v $ m `M.restrictKeys` ys+ -- y is not in m+ GT -> toMap n `M.restrictKeys` ys+{-# INLINE restrictKeys #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Remove all keys in a 'Data.Set.Set' from+-- an 'NEIntMap'.+--+-- @+-- m \`withoutKeys\` s = 'filterWithKey' (\k _ -> k ``Set.notMember`` s) m+-- m \`withoutKeys\` s = m ``difference`` 'fromSet' (const ()) s+-- @+withoutKeys ::+ NEIntMap a ->+ IntSet ->+ IntMap a+withoutKeys n@(NEIntMap k v m) xs = case S.minView xs of+ Nothing -> toMap n+ Just (y, ys) -> case compare k y of+ -- k is not in xs, so cannot be deleted+ LT -> insertMinMap k v $ m `M.withoutKeys` xs+ -- y deletes k, and only k+ EQ -> m `M.withoutKeys` ys+ -- y is not in n, so cannot delete anything, so we can just difference n and ys+ GT -> toMap n `M.withoutKeys` ys+{-# INLINE withoutKeys #-}++-- | /O(n)/. Partition the map according to a predicate.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate was true for all items.+-- * @'That' n2@ means that the predicate was false for all items.+-- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the+-- predicate) and @n2@ (all of the items that were false for the+-- predicate).+--+-- See also 'split'.+--+-- > partition (> "a") (fromList ((5,"a") :| [(3,"b")])) == These (singleton 3 "b") (singleton 5 "a")+-- > partition (< "x") (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))+-- > partition (> "x") (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))+partition ::+ (a -> Bool) ->+ NEIntMap a ->+ These (NEIntMap a) (NEIntMap a)+partition f = partitionWithKey (const f)+{-# INLINE partition #-}++-- | /O(n)/. Partition the map according to a predicate.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate was true for all items,+-- returning the original map.+-- * @'That' n2@ means that the predicate was false for all items,+-- returning the original map.+-- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the+-- predicate) and @n2@ (all of the items that were false for the+-- predicate).+--+-- See also 'split'.+--+-- > partitionWithKey (\ k _ -> k > 3) (fromList ((5,"a") :| [(3,"b")])) == These (singleton 5 "a") (singleton 3 "b")+-- > partitionWithKey (\ k _ -> k < 7) (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))+-- > partitionWithKey (\ k _ -> k > 7) (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))+partitionWithKey ::+ (Key -> a -> Bool) ->+ NEIntMap a ->+ These (NEIntMap a) (NEIntMap a)+partitionWithKey f n@(NEIntMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing)+ | f k v -> This n+ | otherwise -> That n+ (Just n1, Nothing)+ | f k v -> This n+ | otherwise -> These n1 (singleton k v)+ (Nothing, Just n2)+ | f k v -> These (singleton k v) n2+ | otherwise -> That n+ (Just n1, Just n2)+ | f k v -> These (insertMapMin k v m1) n2+ | otherwise -> These n1 (insertMapMin k v m2)+ where+ (m1, m2) = M.partitionWithKey f m0+{-# INLINEABLE partitionWithKey #-}++-- | /O(n)/. Map values and collect the 'Just' results.+--+-- Returns a potentially empty map ('IntMap'), because the function could+-- potentially return 'Nothing' on all items in the 'NEIntMap'.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > mapMaybe f (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "new a"+mapMaybe ::+ (a -> Maybe b) ->+ NEIntMap a ->+ IntMap b+mapMaybe f = mapMaybeWithKey (const f)+{-# INLINE mapMaybe #-}++-- | /O(n)/. Map keys\/values and collect the 'Just' results.+--+-- Returns a potentially empty map ('IntMap'), because the function could+-- potentially return 'Nothing' on all items in the 'NEIntMap'.+--+-- > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing+-- > mapMaybeWithKey f (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "key : 3"+mapMaybeWithKey ::+ (Key -> a -> Maybe b) ->+ NEIntMap a ->+ IntMap b+mapMaybeWithKey f (NEIntMap k v m) = maybe id (insertMinMap k) (f k v) (M.mapMaybeWithKey f m)+{-# INLINE mapMaybeWithKey #-}++-- | /O(n)/. Map values and separate the 'Left' and 'Right' results.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the results were all 'Left'.+-- * @'That' n2@ means that the results were all 'Right'.+-- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')+-- and @n2@ (the map where the results were 'Right')+--+-- > let f a = if a < "c" then Left a else Right a+-- > mapEither f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == These (fromList ((3,"b") :| [(5,"a")])) (fromList ((1,"x") :| [(7,"z")]))+-- >+-- > mapEither (\ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == That (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+mapEither ::+ (a -> Either b c) ->+ NEIntMap a ->+ These (NEIntMap b) (NEIntMap c)+mapEither f = mapEitherWithKey (const f)+{-# INLINE mapEither #-}++-- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the results were all 'Left'.+-- * @'That' n2@ means that the results were all 'Right'.+-- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')+-- and @n2@ (the map where the results were 'Right')+--+-- > let f k a = if k < 5 then Left (k * 2) else Right (a ++ a)+-- > mapEitherWithKey f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == These (fromList ((1,2) :| [(3,6)])) (fromList ((5,"aa") :| [(7,"zz")]))+-- >+-- > mapEitherWithKey (\_ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == That (fromList ((1,"x") :| [(3,"b"), (5,"a"), (7,"z")]))+mapEitherWithKey ::+ (Key -> a -> Either b c) ->+ NEIntMap a ->+ These (NEIntMap b) (NEIntMap c)+mapEitherWithKey f (NEIntMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> case f k v of+ Left v' -> This (singleton k v')+ Right v' -> That (singleton k v')+ (Just n1, Nothing) -> case f k v of+ Left v' -> This (insertMapMin k v' m1)+ Right v' -> These n1 (singleton k v')+ (Nothing, Just n2) -> case f k v of+ Left v' -> These (singleton k v') n2+ Right v' -> That (insertMapMin k v' m2)+ (Just n1, Just n2) -> case f k v of+ Left v' -> These (insertMapMin k v' m1) n2+ Right v' -> These n1 (insertMapMin k v' m2)+ where+ (m1, m2) = M.mapEitherWithKey f m0+{-# INLINEABLE mapEitherWithKey #-}++-- | /O(log n)/. The expression (@'split' k map@) is potentially a 'These'+-- containing up to two 'NEIntMap's based on splitting the map into maps+-- containing items before and after the given key @k@. It will never+-- return a map that contains @k@ itself.+--+-- * 'Nothing' means that @k@ was the only key in the the original map,+-- and so there are no items before or after it.+-- * @'Just' ('This' n1)@ means @k@ was larger than or equal to all items+-- in the map, and @n1@ is the entire original map (minus @k@, if it was+-- present)+-- * @'Just' ('That' n2)@ means @k@ was smaller than or equal to all+-- items in the map, and @n2@ is the entire original map (minus @k@, if+-- it was present)+-- * @'Just' ('These' n1 n2)@ gives @n1@ (the map of all keys from the+-- original map less than @k@) and @n2@ (the map of all keys from the+-- original map greater than @k@)+--+-- > split 2 (fromList ((5,"a") :| [(3,"b")])) == Just (That (fromList ((3,"b") :| [(5,"a")])) )+-- > split 3 (fromList ((5,"a") :| [(3,"b")])) == Just (That (singleton 5 "a") )+-- > split 4 (fromList ((5,"a") :| [(3,"b")])) == Just (These (singleton 3 "b") (singleton 5 "a"))+-- > split 5 (fromList ((5,"a") :| [(3,"b")])) == Just (This (singleton 3 "b") )+-- > split 6 (fromList ((5,"a") :| [(3,"b")])) == Just (This (fromList ((3,"b") :| [(5,"a")])) )+-- > split 5 (singleton 5 "a") == Nothing+split ::+ Key ->+ NEIntMap a ->+ Maybe (These (NEIntMap a) (NEIntMap a))+split k n@(NEIntMap k0 v m0) = case compare k k0 of+ LT -> Just $ That n+ EQ -> That <$> nonEmptyMap m0+ GT -> Just $ case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k0 v)+ (Just _, Nothing) -> This (insertMapMin k0 v m1)+ (Nothing, Just n2) -> These (singleton k0 v) n2+ (Just _, Just n2) -> These (insertMapMin k0 v m1) n2+ where+ (m1, m2) = M.split k m0+{-# INLINEABLE split #-}++-- | /O(log n)/. The expression (@'splitLookup' k map@) splits a map just+-- like 'split' but also returns @'lookup' k map@, as the first field in+-- the 'These':+--+-- > splitLookup 2 (fromList ((5,"a") :| [(3,"b")])) == That (That (fromList ((3,"b") :| [(5,"a")])))+-- > splitLookup 3 (fromList ((5,"a") :| [(3,"b")])) == These "b" (That (singleton 5 "a"))+-- > splitLookup 4 (fromList ((5,"a") :| [(3,"b")])) == That (These (singleton 3 "b") (singleton 5 "a"))+-- > splitLookup 5 (fromList ((5,"a") :| [(3,"b")])) == These "a" (This (singleton 3 "b"))+-- > splitLookup 6 (fromList ((5,"a") :| [(3,"b")])) == That (This (fromList ((3,"b") :| [(5,"a")])))+-- > splitLookup 5 (singleton 5 "a") == This "a"+splitLookup ::+ Key ->+ NEIntMap a ->+ These a (These (NEIntMap a) (NEIntMap a))+splitLookup k n@(NEIntMap k0 v0 m0) = case compare k k0 of+ LT -> That . That $ n+ EQ -> maybe (This v0) (These v0 . That) . nonEmptyMap $ m0+ GT -> maybe That These v $ case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k0 v0)+ (Just _, Nothing) -> This (insertMapMin k0 v0 m1)+ (Nothing, Just n2) -> These (singleton k0 v0) n2+ (Just _, Just n2) -> These (insertMapMin k0 v0 m1) n2+ where+ (m1, v, m2) = M.splitLookup k m0+{-# INLINEABLE splitLookup #-}++-- | /O(1)/. Decompose a map into pieces based on the structure of the+-- underlying tree. This function is useful for consuming a map in+-- parallel.+--+-- No guarantee is made as to the sizes of the pieces; an internal, but+-- deterministic process determines this. However, it is guaranteed that+-- the pieces returned will be in ascending order (all elements in the+-- first submap less than all elements in the second, and so on).+--+-- Note that the current implementation does not return more than four+-- submaps, but you should not depend on this behaviour because it can+-- change in the future without notice.+splitRoot ::+ NEIntMap a ->+ NonEmpty (NEIntMap a)+splitRoot (NEIntMap k v m) =+ singleton k v+ :| Maybe.mapMaybe nonEmptyMap (M.splitRoot m)+{-# INLINE splitRoot #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).+isSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool+isSubmapOf = isSubmapOfBy (==)+{-# INLINE isSubmapOf #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if+-- all keys in @t1@ are in tree @t2@, and when @f@ returns 'True' when+-- applied to their respective values. For example, the following+-- expressions are all 'True':+--+-- > isSubmapOfBy (==) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (<=) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (fromList (('a',1) :| [('b',2)]))+--+-- But the following are all 'False':+--+-- > isSubmapOfBy (==) (singleton 'a' 2) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (<) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (singleton 'a' 1)+isSubmapOfBy ::+ (a -> b -> Bool) ->+ NEIntMap a ->+ NEIntMap b ->+ Bool+isSubmapOfBy f (NEIntMap k v m0) (toMap -> m1) =+ kvSub+ && M.isSubmapOfBy f m0 m1+ where+ kvSub = case M.lookup k m1 of+ Just v0 -> f v v0+ Nothing -> False+{-# INLINE isSubmapOfBy #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Is this a proper submap? (ie. a submap+-- but not equal). Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy'+-- (==)@).+isProperSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool+isProperSubmapOf = isProperSubmapOfBy (==)+{-# INLINE isProperSubmapOf #-}++-- | /O(m*log(n\/m + 1)), m <= n/. 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 values. For+-- example, the following expressions are all 'True':+--+-- > isProperSubmapOfBy (==) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+-- > isProperSubmapOfBy (<=) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+--+-- But the following are all 'False':+--+-- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (fromList ((1,1) :| [(2,2)]))+-- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (singleton 1 1))+-- > isProperSubmapOfBy (<) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+isProperSubmapOfBy ::+ (a -> b -> Bool) ->+ NEIntMap a ->+ NEIntMap b ->+ Bool+isProperSubmapOfBy f m1 m2 =+ M.size (neimIntMap m1) < M.size (neimIntMap m2)+ && isSubmapOfBy f m1 m2+{-# INLINE isProperSubmapOfBy #-}++-- | /O(1)/. The minimal key of the map. Note that this is total, making+-- 'Data.IntMap.lookupMin' obsolete. It is constant-time, so has better+-- asymptotics than @Data.IntMap.lookupMin@ and @Data.IntMap.findMin@, as well.+--+-- > findMin (fromList ((5,"a") :| [(3,"b")])) == (3,"b")+findMin :: NEIntMap a -> (Key, a)+findMin (NEIntMap k v _) = (k, v)+{-# INLINE findMin #-}++-- | /O(log n)/. The maximal key of the map. Note that this is total, making+-- 'Data.IntMap.lookupMin' obsolete.+--+-- > findMax (fromList ((5,"a") :| [(3,"b")])) == (5,"a")+findMax :: NEIntMap a -> (Key, a)+findMax (NEIntMap k v m) = fromMaybe (k, v) . M.lookupMax $ m+{-# INLINE findMax #-}++-- | /O(1)/. Delete the minimal key. Returns a potentially empty map+-- ('IntMap'), because we might end up deleting the final key in a singleton+-- map. It is constant-time, so has better asymptotics than+-- 'Data.IntMap.deleteMin'.+--+-- > deleteMin (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.IntMap.fromList [(5,"a"), (7,"c")]+-- > deleteMin (singleton 5 "a") == Data.IntMap.empty+deleteMin :: NEIntMap a -> IntMap a+deleteMin (NEIntMap _ _ m) = m+{-# INLINE deleteMin #-}++-- | /O(log n)/. Delete the maximal key. Returns a potentially empty map+-- ('IntMap'), because we might end up deleting the final key in a singleton+-- map.+--+-- > deleteMax (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.IntMap.fromList [(3,"b"), (5,"a")]+-- > deleteMax (singleton 5 "a") == Data.IntMap.empty+deleteMax :: NEIntMap a -> IntMap a+deleteMax (NEIntMap k v m) = case M.maxView m of+ Nothing -> M.empty+ Just (_, m') -> insertMinMap k v m'+{-# INLINE deleteMax #-}++-- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the+-- minimal key. Returns a potentially empty map ('IntMap'), because we might+-- end up deleting the final key in the map if the function returns+-- 'Nothing'. See 'adjustMin' for a version that can guaruntee that we+-- return a non-empty map.+--+-- > updateMin (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "Xb"), (5, "a")]+-- > updateMin (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+updateMin :: (a -> Maybe a) -> NEIntMap a -> IntMap a+updateMin f = updateMinWithKey (const f)+{-# INLINE updateMin #-}++-- | /O(1)/. A version of 'updateMin' that disallows deletion, allowing us+-- to guarantee that the result is also non-empty.+adjustMin :: (a -> a) -> NEIntMap a -> NEIntMap a+adjustMin f = adjustMinWithKey (const f)+{-# INLINE adjustMin #-}++-- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the+-- minimal key. Returns a potentially empty map ('IntMap'), because we might+-- end up deleting the final key in the map if the function returns+-- 'Nothing'. See 'adjustMinWithKey' for a version that guaruntees+-- a non-empty map.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+updateMinWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a+updateMinWithKey f (NEIntMap k v m) = maybe id (insertMinMap k) (f k v) m+{-# INLINE updateMinWithKey #-}++-- | /O(1)/. A version of 'adjustMaxWithKey' that disallows deletion,+-- allowing us to guarantee that the result is also non-empty. Note that+-- it also is able to have better asymptotics than 'updateMinWithKey' in+-- general.+adjustMinWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a+adjustMinWithKey f (NEIntMap k v m) = NEIntMap k (f k v) m+{-# INLINE adjustMinWithKey #-}++-- | /O(log n)/. Update the value at the maximal key. Returns+-- a potentially empty map ('IntMap'), because we might end up deleting the+-- final key in the map if the function returns 'Nothing'. See 'adjustMax'+-- for a version that can guarantee that we return a non-empty map.+--+-- > updateMax (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "Xa")]+-- > updateMax (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"+updateMax :: (a -> Maybe a) -> NEIntMap a -> IntMap a+updateMax f = updateMaxWithKey (const f)+{-# INLINE updateMax #-}++-- | /O(log n)/. A version of 'updateMax' that disallows deletion, allowing+-- us to guarantee that the result is also non-empty.+adjustMax :: (a -> a) -> NEIntMap a -> NEIntMap a+adjustMax f = adjustMaxWithKey (const f)+{-# INLINE adjustMax #-}++-- | /O(log n)/. Update the value at the maximal key. Returns+-- a potentially empty map ('IntMap'), because we might end up deleting the+-- final key in the map if the function returns 'Nothing'. See+-- 'adjustMaxWithKey' for a version that guaruntees a non-empty map.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+updateMaxWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a+updateMaxWithKey f (NEIntMap k v m)+ | M.null m = maybe m (M.singleton k) $ f k v+ | otherwise =+ insertMinMap k v+ . M.updateMaxWithKey f+ $ m+{-# INLINE updateMaxWithKey #-}++-- | /O(log n)/. A version of 'updateMaxWithKey' that disallows deletion,+-- allowing us to guarantee that the result is also non-empty.+adjustMaxWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a+adjustMaxWithKey f (NEIntMap k0 v m)+ | M.null m = NEIntMap k0 (f k0 v) m+ | otherwise =+ insertMapMin k0 v+ . M.updateMaxWithKey (\k -> Just . f k)+ $ m+{-# INLINE adjustMaxWithKey #-}++-- | /O(1)/. Retrieves the value associated with minimal key of the+-- map, and the map stripped of that element. It is constant-time, so has+-- better asymptotics than @Data.IntMap.minView@ for 'IntMap'.+--+-- Note that unlike @Data.IntMap.minView@ for 'IntMap', this cannot ever fail,+-- so doesn't need to return in a 'Maybe'. However, the result 'IntMap' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > minView (fromList ((5,"a") :| [(3,"b")])) == ("b", Data.IntMap.singleton 5 "a")+minView :: NEIntMap a -> (a, IntMap a)+minView = first snd . deleteFindMin+{-# INLINE minView #-}++-- | /O(1)/. Delete and find the minimal key-value pair. It is+-- constant-time, so has better asymptotics that @Data.IntMap.minView@ for+-- 'IntMap'.+--+-- Note that unlike @Data.IntMap.deleteFindMin@ for 'IntMap', this cannot ever+-- fail, and so is a total function. However, the result 'IntMap' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > deleteFindMin (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((3,"b"), Data.IntMap.fromList [(5,"a"), (10,"c")])+deleteFindMin :: NEIntMap a -> ((Key, a), IntMap a)+deleteFindMin (NEIntMap k v m) = ((k, v), m)+{-# INLINE deleteFindMin #-}++-- | /O(log n)/. Retrieves the value associated with maximal key of the+-- map, and the map stripped of that element.+--+-- Note that unlike @Data.IntMap.maxView@ from 'IntMap', this cannot ever fail,+-- so doesn't need to return in a 'Maybe'. However, the result 'IntMap' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > maxView (fromList ((5,"a") :| [(3,"b")])) == ("a", Data.IntMap.singleton 3 "b")+maxView :: NEIntMap a -> (a, IntMap a)+maxView = first snd . deleteFindMax+{-# INLINE maxView #-}++-- | /O(log n)/. Delete and find the minimal key-value pair.+--+-- Note that unlike @Data.IntMap.deleteFindMax@ for 'IntMap', this cannot ever+-- fail, and so is a total function. However, the result 'IntMap' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > deleteFindMax (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((10,"c"), Data.IntMap.fromList [(3,"b"), (5,"a")])+deleteFindMax :: NEIntMap a -> ((Key, a), IntMap a)+deleteFindMax (NEIntMap k v m) =+ maybe ((k, v), M.empty) (second (insertMinMap k v))+ . M.maxViewWithKey+ $ m+{-# INLINE deleteFindMax #-}++-- ---------------------------+-- Combining functions+-- ---------------------------+--+-- Code comes from "Data.Map.Internal" from containers, modified slightly+-- to work with NonEmpty+--+-- Copyright : (c) Daan Leijen 2002+-- (c) Andriy Palamarchuk 2008++combineEq :: NonEmpty (Key, b) -> NonEmpty (Key, b)+combineEq = \case+ x :| [] -> x :| []+ x :| xx@(_ : _) -> go x xx+ where+ go z [] = z :| []+ go z@(kz, _) (x@(kx, xx) : xs')+ | kx == kz = go (kx, xx) xs'+ | otherwise = z NE.<| go x xs'++combineEqWith ::+ (Key -> b -> b -> b) ->+ NonEmpty (Key, b) ->+ NonEmpty (Key, b)+combineEqWith f = \case+ x :| [] -> x :| []+ x :| xx@(_ : _) -> go x xx+ where+ go z [] = z :| []+ go z@(kz, zz) (x@(kx, xx) : xs')+ | kx == kz = let yy = f kx xx zz in go (kx, yy) xs'+ | otherwise = z NE.<| go x xs'
+ src/Data/IntMap/NonEmpty/Lazy/Internal.hs view
@@ -0,0 +1,739 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ViewPatterns #-}+{-# OPTIONS_HADDOCK not-home #-}++-- |+-- Module : Data.IntMap.NonEmpty.Lazy.Internal+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- Unsafe internal-use functions used in the implementation of+-- "Data.IntMap.NonEmpty.Lazy". These functions can potentially be used to+-- break the abstraction of 'NEIntMap' and produce unsound maps, so be+-- wary!+module Data.IntMap.NonEmpty.Lazy.Internal (+ -- * Non-Empty IntMap type+ NEIntMap (..),+ Key,+ singleton,+ nonEmptyMap,+ withNonEmpty,+ fromList,+ toList,+ map,+ insertWith,+ union,+ unions,+ elems,+ size,+ toMap,++ -- * Folds+ foldr,+ foldr',+ foldr1,+ foldl,+ foldl',+ foldl1,++ -- * Traversals+ traverseWithKey,+ traverseWithKey1,+ foldMapWithKey,++ -- * Unsafe IntMap Functions+ insertMinMap,+ insertMaxMap,++ -- * Debug+ valid,+) where++import Control.Applicative+import Control.Comonad+import Control.DeepSeq+import Control.Monad+import qualified Data.Aeson as A+import Data.Coerce+import Data.Data+import qualified Data.Foldable as F+import Data.Foldable.WithIndex (FoldableWithIndex (..))+import Data.Function+import Data.Functor.Alt+import Data.Functor.Classes+import Data.Functor.Invariant+import Data.Functor.WithIndex (FunctorWithIndex (..))+import qualified Data.IntMap as M+import Data.IntMap.Internal (IntMap (..), Key)+import qualified Data.List as L+import Data.List.NonEmpty (NonEmpty (..))+import Data.Maybe+import Data.Semigroup+import Data.Semigroup.Foldable (Foldable1 (fold1))+import qualified Data.Semigroup.Foldable as F1+import Data.Semigroup.Traversable (Traversable1 (..))+import Data.Traversable.WithIndex (TraversableWithIndex (..))+import qualified GHC.Exts as Exts+import Text.Read+import Prelude hiding (Foldable (..), map)++-- | A non-empty (by construction) map from integer keys to values @a@. At+-- least one key-value pair exists in an @'NEIntMap' v@ at all times.+--+-- Functions that /take/ an 'NEIntMap' can safely operate on it with the+-- assumption that it has at least one key-value pair.+--+-- Functions that /return/ an 'NEIntMap' provide an assurance that the result+-- has at least one key-value pair.+--+-- "Data.IntMap.NonEmpty.Lazy" re-exports the API of "Data.IntMap.Lazy", faithfully+-- reproducing asymptotics, typeclass constraints, and semantics.+-- Functions that ensure that input and output maps are both non-empty+-- (like 'Data.IntMap.NonEmpty.Lazy.insert') return 'NEIntMap', but functions that+-- might potentially return an empty map (like 'Data.IntMap.NonEmpty.Lazy.delete')+-- return a 'IntMap' instead.+--+-- You can directly construct an 'NEIntMap' with the API from+-- "Data.IntMap.NonEmpty.Lazy"; it's more or less the same as constructing a normal+-- 'IntMap', except you don't have access to 'Data.IntMap.empty'. There are also+-- a few ways to construct an 'NEIntMap' from a 'IntMap':+--+-- 1. The 'nonEmptyMap' smart constructor will convert a @'IntMap' k a@ into+-- a @'Maybe' ('NEIntMap' k a)@, returning 'Nothing' if the original 'IntMap'+-- was empty.+-- 2. You can use the 'Data.IntMap.NonEmpty.insertIntMap' family of functions to+-- insert a value into a 'IntMap' to create a guaranteed 'NEIntMap'.+-- 3. You can use the 'Data.IntMap.NonEmpty.Lazy.IsNonEmpty' and+-- 'Data.IntMap.NonEmpty.Lazy.IsEmpty' patterns to "pattern match" on a 'IntMap'+-- to reveal it as either containing a 'NEIntMap' or an empty map.+-- 4. 'withNonEmpty' offers a continuation-based interface for+-- deconstructing a 'IntMap' and treating it as if it were an+-- 'NEIntMap'.+--+-- You can convert an 'NEIntMap' into a 'IntMap' with 'toMap' or+-- 'Data.IntMap.NonEmpty.Lazy.IsNonEmpty', essentially "obscuring" the non-empty+-- property from the type.+data NEIntMap a+ = NEIntMap+ { neimK0 :: !Key+ -- ^ invariant: must be smaller than smallest key in map+ , neimV0 :: a+ , neimIntMap :: !(IntMap a)+ }+ deriving (Typeable)++instance Eq a => Eq (NEIntMap a) where+ t1 == t2 =+ M.size (neimIntMap t1) == M.size (neimIntMap t2)+ && toList t1 == toList t2++instance Ord a => Ord (NEIntMap a) where+ compare = compare `on` toList+ (<) = (<) `on` toList+ (>) = (>) `on` toList+ (<=) = (<=) `on` toList+ (>=) = (>=) `on` toList++-- | @since 0.3.6.0+instance FunctorWithIndex Int NEIntMap where+ imap f (NEIntMap k v m) = NEIntMap k (f k v) (M.mapWithKey f m)++-- | @since 0.3.6.0+instance FoldableWithIndex Int NEIntMap where+ ifoldMap = foldMapWithKey++-- | @since 0.3.6.0+instance TraversableWithIndex Int NEIntMap where+ itraverse f (NEIntMap k v m) =+ NEIntMap k+ <$> f k v+ <*> M.traverseWithKey f m++-- | @since 0.3.6.0+instance Exts.IsList (NEIntMap a) where+ type Item (NEIntMap a) = (Key, a)++ fromList (a : as) = fromList (a :| as)+ fromList [] = errorWithoutStackTrace "Data.IntMap.NonEmpty.fromList: empty list"++ toList = F.toList . toList++instance Eq1 NEIntMap where+ liftEq eq m1 m2 =+ M.size (neimIntMap m1) == M.size (neimIntMap m2)+ && liftEq (liftEq eq) (toList m1) (toList m2)++instance Ord1 NEIntMap where+ liftCompare cmp m n =+ liftCompare (liftCompare cmp) (toList m) (toList n)++instance Show1 NEIntMap where+ liftShowsPrec sp sl d m =+ showsUnaryWith (liftShowsPrec sp' sl') "fromList" d (toList m)+ where+ sp' = liftShowsPrec sp sl+ sl' = liftShowList sp sl++instance Read1 NEIntMap where+ liftReadsPrec rp rl =+ readsData $+ readsUnaryWith (liftReadsPrec rp' rl') "fromList" fromList+ where+ rp' = liftReadsPrec rp rl+ rl' = liftReadList rp rl++instance Read e => Read (NEIntMap e) where+ readPrec = parens $ prec 10 $ do+ Ident "fromList" <- lexP+ xs <- parens . prec 10 $ readPrec+ return (fromList xs)+ readListPrec = readListPrecDefault++instance Show a => Show (NEIntMap a) where+ showsPrec d m =+ showParen (d > 10) $+ showString "fromList (" . shows (toList m) . showString ")"++instance NFData a => NFData (NEIntMap a) where+ rnf (NEIntMap k v a) = rnf k `seq` rnf v `seq` rnf a++-- Data instance code from Data.IntMap.Internal+--+-- Copyright : (c) Daan Leijen 2002+-- (c) Andriy Palamarchuk 2008+-- (c) wren romano 2016+#if MIN_VERSION_base(4,16,0)+instance Data a => Data (NEIntMap a) where+ gfoldl f z im = z fromList `f` toList im+ toConstr _ = fromListConstr+ gunfold k z c = case constrIndex c of+ 1 -> k (z fromList)+ _ -> error "gunfold"+ dataTypeOf _ = intMapDataType+ dataCast1 = gcast1+#else+#ifndef __HLINT__+instance Data a => Data (NEIntMap a) where+ gfoldl f z im = z fromList `f` toList im+ toConstr _ = fromListConstr+ gunfold k z c = case constrIndex c of+ 1 -> k (z fromList)+ _ -> error "gunfold"+ dataTypeOf _ = intMapDataType+ dataCast1 f = gcast1 f+#endif+#endif++fromListConstr :: Constr+fromListConstr = mkConstr intMapDataType "fromList" [] Prefix++intMapDataType :: DataType+intMapDataType = mkDataType "Data.IntMap.NonEmpty.Internal.NEIntMap" [fromListConstr]++instance A.ToJSON a => A.ToJSON (NEIntMap a) where+ toJSON = A.toJSON . toMap+ toEncoding = A.toEncoding . toMap++instance A.FromJSON a => A.FromJSON (NEIntMap a) where+ parseJSON =+ withNonEmpty (fail err) pure+ <=< A.parseJSON+ where+ err = "NEIntMap: Non-empty map expected, but empty map found"++-- | @since 0.3.4.4+instance Alt NEIntMap where+ (<!>) = union++-- | /O(n)/. Fold the values in the map using the given right-associative+-- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'elems'@.+--+-- > elemsList map = foldr (:) [] map+--+-- > let f a len = len + (length a)+-- > foldr f 0 (fromList ((5,"a") :| [(3,"bbb")])) == 4+foldr :: (a -> b -> b) -> b -> NEIntMap a -> b+foldr f z (NEIntMap _ v m) = v `f` M.foldr f z m+{-# INLINE foldr #-}++-- | /O(n)/. A strict version of 'foldr'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldr' :: (a -> b -> b) -> b -> NEIntMap a -> b+foldr' f z (NEIntMap _ v m) = v `f` y+ where+ !y = M.foldr' f z m+{-# INLINE foldr' #-}++-- | /O(n)/. A version of 'foldr' that uses the value at the maximal key in+-- the map as the starting value.+--+-- Note that, unlike 'Data.Foldable.foldr1' for 'IntMap', this function is+-- total if the input function is total.+foldr1 :: (a -> a -> a) -> NEIntMap a -> a+foldr1 f (NEIntMap _ v m) =+ maybe v (f v . uncurry (M.foldr f))+ . M.maxView+ $ m+{-# INLINE foldr1 #-}++-- | /O(n)/. Fold the values in the map using the given left-associative+-- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'elems'@.+--+-- > elemsList = reverse . foldl (flip (:)) []+--+-- > let f len a = len + (length a)+-- > foldl f 0 (fromList ((5,"a") :| [(3,"bbb")])) == 4+foldl :: (a -> b -> a) -> a -> NEIntMap b -> a+foldl f z (NEIntMap _ v m) = M.foldl f (f z v) m+{-# INLINE foldl #-}++-- | /O(n)/. A strict version of 'foldl'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldl' :: (a -> b -> a) -> a -> NEIntMap b -> a+foldl' f z (NEIntMap _ v m) = M.foldl' f x m+ where+ !x = f z v+{-# INLINE foldl' #-}++-- | /O(n)/. A version of 'foldl' that uses the value at the minimal key in+-- the map as the starting value.+--+-- Note that, unlike 'Data.Foldable.foldl1' for 'IntMap', this function is+-- total if the input function is total.+foldl1 :: (a -> a -> a) -> NEIntMap a -> a+foldl1 f (NEIntMap _ v m) = M.foldl f v m+{-# INLINE foldl1 #-}++-- | /O(n)/. Fold the keys and values in the map using the given semigroup,+-- such that+--+-- @'foldMapWithKey' f = 'Data.Semigroup.Foldable.fold1' . 'Data.IntMap.NonEmpty.mapWithKey' f@+--+-- __WARNING__: Differs from @Data.IntMap.foldMapWithKey@, which traverses+-- positive items first, then negative items.+--+-- This can be an asymptotically faster than+-- 'Data.IntMap.NonEmpty.foldrWithKey' or 'Data.IntMap.NonEmpty.foldlWithKey' for+-- some monoids.++-- TODO: benchmark against maxView method+foldMapWithKey ::+ Semigroup m =>+ (Key -> a -> m) ->+ NEIntMap a ->+ m+foldMapWithKey f = F1.foldMap1 (uncurry f) . toList+{-# INLINE foldMapWithKey #-}++-- | /O(n)/. IntMap a function over all values in the map.+--+-- > map (++ "x") (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "bx") :| [(5, "ax")])+map :: (a -> b) -> NEIntMap a -> NEIntMap b+map f (NEIntMap k0 v m) = NEIntMap k0 (f v) (M.map f m)+{-# NOINLINE [1] map #-}++{-# RULES+"map/map" forall f g xs. map f (map g xs) = map (f . g) xs+ #-}+{-# RULES+"map/coerce" map coerce = coerce+ #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- 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' == 'Data.IntMap.NonEmpty.unionWith' 'const'@).+--+-- > union (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "a"), (7, "C")])+union ::+ NEIntMap a ->+ NEIntMap a ->+ NEIntMap a+union n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEIntMap k1 v1 . M.union m1 . toMap $ n2+ EQ -> NEIntMap k1 v1 . M.union m1 $ m2+ GT -> NEIntMap k2 v2 . M.union (toMap n1) $ m2+{-# INLINE union #-}++-- | The left-biased union of a non-empty list of maps.+--+-- > unions (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])+-- > == fromList [(3, "b"), (5, "a"), (7, "C")]+-- > unions (fromList ((5, "A3") :| [(3, "B3")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "a") :| [(3, "b")])])+-- > == fromList ((3, "B3") :| [(5, "A3"), (7, "C")])+unions ::+ Foldable1 f =>+ f (NEIntMap a) ->+ NEIntMap a+unions (F1.toNonEmpty -> (m :| ms)) = F.foldl' union m ms+{-# INLINE unions #-}++-- | /O(n)/.+-- Return all elements of the map in the ascending order of their keys.+--+-- > elems (fromList ((5,"a") :| [(3,"b")])) == ("b" :| ["a"])+elems :: NEIntMap a -> NonEmpty a+elems (NEIntMap _ v m) = v :| M.elems m+{-# INLINE elems #-}++-- | /O(1)/. The number of elements in the map. Guaranteed to be greater+-- than zero.+--+-- > size (singleton 1 'a') == 1+-- > size (fromList ((1,'a') :| [(2,'c'), (3,'b')])) == 3+size :: NEIntMap a -> Int+size (NEIntMap _ _ m) = 1 + M.size m+{-# INLINE size #-}++-- | /O(log n)/.+-- Convert a non-empty map back into a normal possibly-empty map, for usage+-- with functions that expect 'IntMap'.+--+-- Can be thought of as "obscuring" the non-emptiness of the map in its+-- type. See the 'Data.IntMap.NonEmpty.IsNotEmpty' pattern.+--+-- 'nonEmptyMap' and @'maybe' 'Data.IntMap.empty' 'toMap'@ form an isomorphism: they+-- are perfect structure-preserving inverses of eachother.+--+-- > toMap (fromList ((3,"a") :| [(5,"b")])) == Data.IntMap.fromList [(3,"a"), (5,"b")]+toMap :: NEIntMap a -> IntMap a+toMap (NEIntMap k v m) = insertMinMap k v m+{-# INLINE toMap #-}++-- | /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.+--+-- /Use 'traverseWithKey1'/ whenever possible (if your 'Applicative'+-- also has 'Apply' instance). This version is provided only for types+-- that do not have 'Apply' instance, since 'Apply' is not at the moment+-- (and might not ever be) an official superclass of 'Applicative'.+--+-- __WARNING__: Differs from @Data.IntMap.traverseWithKey@, which traverses+-- positive items first, then negative items.+--+-- @+-- 'traverseWithKey' f = 'unwrapApplicative' . 'traverseWithKey1' (\\k -> WrapApplicative . f k)+-- @+traverseWithKey ::+ Applicative t =>+ (Key -> a -> t b) ->+ NEIntMap a ->+ t (NEIntMap b)+traverseWithKey f (NEIntMap k v m0) =+ NEIntMap k+ <$> f k v+ <*> M.traverseWithKey f m0+{-# INLINE traverseWithKey #-}++-- | /O(n)/.+-- @'traverseWithKey1' f m == 'fromList' <$> 'traverse1' (\(k, v) -> (,) k <$> f k v) ('toList' m)@+--+-- That is, behaves exactly like a regular 'traverse1' except that the traversing+-- function also has access to the key associated with a value.+--+-- __WARNING__: Differs from @Data.IntMap.traverseWithKey@, which traverses+-- positive items first, then negative items.+--+-- Is more general than 'traverseWithKey', since works with all 'Apply',+-- and not just 'Applicative'.++-- TODO: benchmark against maxView-based methods+traverseWithKey1 ::+ Apply t =>+ (Key -> a -> t b) ->+ NEIntMap a ->+ t (NEIntMap b)+traverseWithKey1 f (NEIntMap k0 v m0) = case runMaybeApply m1 of+ Left m2 -> NEIntMap k0 <$> f k0 v <.> m2+ Right m2 -> flip (NEIntMap k0) m2 <$> f k0 v+ where+ m1 = M.traverseWithKey (\k -> MaybeApply . Left . f k) m0+{-# INLINEABLE traverseWithKey1 #-}++-- | /O(n)/. Convert the map to a non-empty list of key\/value pairs.+--+-- > toList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+toList :: NEIntMap a -> NonEmpty (Key, a)+toList (NEIntMap k v m) = (k, v) :| M.toList m+{-# INLINE toList #-}++-- | /O(log n)/. Smart constructor for an 'NEIntMap' from a 'IntMap'. Returns+-- 'Nothing' if the 'IntMap' was originally actually empty, and @'Just' n@+-- with an 'NEIntMap', if the 'IntMap' was not empty.+--+-- 'nonEmptyMap' and @'maybe' 'Data.IntMap.empty' 'toMap'@ form an+-- isomorphism: they are perfect structure-preserving inverses of+-- eachother.+--+-- See 'Data.IntMap.NonEmpty.IsNonEmpty' for a pattern synonym that lets you+-- "match on" the possiblity of a 'IntMap' being an 'NEIntMap'.+--+-- > nonEmptyMap (Data.IntMap.fromList [(3,"a"), (5,"b")]) == Just (fromList ((3,"a") :| [(5,"b")]))+nonEmptyMap :: IntMap a -> Maybe (NEIntMap a)+nonEmptyMap = (fmap . uncurry . uncurry) NEIntMap . M.minViewWithKey+{-# INLINE nonEmptyMap #-}++-- | /O(log n)/. A general continuation-based way to consume a 'IntMap' as if+-- it were an 'NEIntMap'. @'withNonEmpty' def f@ will take a 'IntMap'. If map is+-- empty, it will evaluate to @def@. Otherwise, a non-empty map 'NEIntMap'+-- will be fed to the function @f@ instead.+--+-- @'nonEmptyMap' == 'withNonEmpty' 'Nothing' 'Just'@+withNonEmpty ::+ -- | value to return if map is empty+ r ->+ -- | function to apply if map is not empty+ (NEIntMap a -> r) ->+ IntMap a ->+ r+withNonEmpty def f = maybe def f . nonEmptyMap+{-# INLINE withNonEmpty #-}++-- | /O(n*log n)/. Build a non-empty map from a non-empty list of+-- key\/value pairs. See also 'Data.IntMap.NonEmpty.fromAscList'. If the list+-- contains more than one value for the same key, the last value for the+-- key is retained.+--+-- > fromList ((5,"a") :| [(3,"b"), (5, "c")]) == fromList ((5,"c") :| [(3,"b")])+-- > fromList ((5,"c") :| [(3,"b"), (5, "a")]) == fromList ((5,"a") :| [(3,"b")])++-- TODO: write manually and optimize to be equivalent to+-- 'fromDistinctAscList' if items are ordered, just like the actual+-- 'M.fromList'.+fromList :: NonEmpty (Key, a) -> NEIntMap a+fromList ((k, v) :| xs) =+ withNonEmpty (singleton k v) (insertWith (const id) k v)+ . M.fromList+ $ xs+{-# INLINE fromList #-}++-- | /O(1)/. A map with a single element.+--+-- > singleton 1 'a' == fromList ((1, 'a') :| [])+-- > size (singleton 1 'a') == 1+singleton :: Key -> a -> NEIntMap a+singleton k v = NEIntMap k v M.empty+{-# INLINE singleton #-}++-- | /O(log n)/. Insert with a function, combining new value and old value.+-- @'insertWith' f key value mp@ will insert the pair (key, value) into+-- @mp@ if key does not exist in the map. If the key does exist, the+-- function will insert the pair @(key, f new_value old_value)@.+--+-- See 'Data.IntMap.NonEmpty.insertIntMapWith' for a version where the first+-- argument is a 'IntMap'.+--+-- > insertWith (++) 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "xxxa")])+-- > insertWith (++) 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+insertWith ::+ (a -> a -> a) ->+ Key ->+ a ->+ NEIntMap a ->+ NEIntMap a+insertWith f k v n@(NEIntMap k0 v0 m) = case compare k k0 of+ LT -> NEIntMap k v . toMap $ n+ EQ -> NEIntMap k (f v v0) m+ GT -> NEIntMap k0 v0 $ M.insertWith f k v m+{-# INLINE insertWith #-}++-- | Left-biased union+instance Semigroup (NEIntMap a) where+ (<>) = union+ {-# INLINE (<>) #-}+ sconcat = unions+ {-# INLINE sconcat #-}++instance Functor NEIntMap where+ fmap = map+ {-# INLINE fmap #-}+ x <$ NEIntMap k _ m = NEIntMap k x (x <$ m)+ {-# INLINE (<$) #-}++-- | @since 0.3.4.4+instance Invariant NEIntMap where+ invmap f _ = fmap f+ {-# INLINE invmap #-}++-- | Traverses elements in order of ascending keys.+--+-- __WARNING:__ 'F.fold' and 'F.foldMap' are different than for the+-- 'IntMap' instance. They traverse elements in order of ascending keys,+-- while 'IntMap' traverses positive keys first, then negative keys.+--+-- 'Data.Foldable.foldr1', 'Data.Foldable.foldl1', 'Data.Foldable.minimum',+-- 'Data.Foldable.maximum' are all total.+#if MIN_VERSION_base(4,11,0)+instance F.Foldable NEIntMap where+ fold (NEIntMap _ v m) = v <> F.fold (M.elems m)+ {-# INLINE fold #-}+ foldMap f (NEIntMap _ v m) = f v <> F.foldMap f (M.elems m)+ {-# INLINE foldMap #-}+ foldr = foldr+ {-# INLINE foldr #-}+ foldr' = foldr'+ {-# INLINE foldr' #-}+ foldr1 = foldr1+ {-# INLINE foldr1 #-}+ foldl = foldl+ {-# INLINE foldl #-}+ foldl' = foldl'+ {-# INLINE foldl' #-}+ foldl1 = foldl1+ {-# INLINE foldl1 #-}+ null _ = False+ {-# INLINE null #-}+ length = size+ {-# INLINE length #-}+ elem x (NEIntMap _ v m) = F.elem x m+ || x == v+ {-# INLINE elem #-}+ -- TODO: use build+ toList = F.toList . elems+ {-# INLINE toList #-}+#else+instance F.Foldable NEIntMap where+ fold (NEIntMap _ v m) = v `mappend` F.fold (M.elems m)+ {-# INLINE fold #-}+ foldMap f (NEIntMap _ v m) = f v `mappend` F.foldMap f (M.elems m)+ {-# INLINE foldMap #-}+ foldr = foldr+ {-# INLINE foldr #-}+ foldr' = foldr'+ {-# INLINE foldr' #-}+ foldr1 = foldr1+ {-# INLINE foldr1 #-}+ foldl = foldl+ {-# INLINE foldl #-}+ foldl' = foldl'+ {-# INLINE foldl' #-}+ foldl1 = foldl1+ {-# INLINE foldl1 #-}+ null _ = False+ {-# INLINE null #-}+ length = size+ {-# INLINE length #-}+ elem x (NEIntMap _ v m) = F.elem x m+ || x == v+ {-# INLINE elem #-}+ -- TODO: use build+ toList = F.toList . elems+ {-# INLINE toList #-}+#endif++-- | Traverses elements in order of ascending keys+--+-- __WARNING:__ Different than for the 'IntMap' instance. They traverse+-- elements in order of ascending keys, while 'IntMap' traverses positive+-- keys first, then negative keys.+instance Traversable NEIntMap where+ traverse f = traverseWithKey (const f)+ {-# INLINE traverse #-}++-- | Traverses elements in order of ascending keys+--+-- __WARNING:__ 'F1.fold1' and 'F1.foldMap1' are different than 'F.fold' and+-- 'F.foldMap' for the 'IntMap' instance of 'Foldable'. They traverse+-- elements in order of ascending keys, while 'IntMap' traverses positive+-- keys first, then negative keys.+#if MIN_VERSION_base(4,11,0)+instance Foldable1 NEIntMap where+ fold1 (NEIntMap _ v m) = maybe v (v <>)+ . F.foldMap Just+ . M.elems+ $ m+ {-# INLINE fold1 #-}+ foldMap1 f = foldMapWithKey (const f)+ {-# INLINE foldMap1 #-}+ toNonEmpty = elems+ {-# INLINE toNonEmpty #-}+#else+instance Foldable1 NEIntMap where+ fold1 (NEIntMap _ v m) = option v (v <>)+ . F.foldMap (Option . Just)+ . M.elems+ $ m+ {-# INLINE fold1 #-}+ foldMap1 f = foldMapWithKey (const f)+ {-# INLINE foldMap1 #-}+ toNonEmpty = elems+ {-# INLINE toNonEmpty #-}+#endif++-- | Traverses elements in order of ascending keys+--+-- __WARNING:__ 'traverse1' and 'sequence1' are different 'traverse' and+-- 'sequence' for the 'IntMap' instance of 'Traversable'. They traverse+-- elements in order of ascending keys, while 'IntMap' traverses positive+-- keys first, then negative keys.+instance Traversable1 NEIntMap where+ traverse1 f = traverseWithKey1 (const f)+ {-# INLINE traverse1 #-}++-- | 'extract' gets the value at the minimal key, and 'duplicate' produces+-- a map of maps comprised of all keys from the original map greater than+-- or equal to the current key.+--+-- @since 0.1.1.0+instance Comonad NEIntMap where+ extract = neimV0+ {-# INLINE extract #-}++ -- We'd like to use 'M.mapAccumWithKey', but it traverses things in the+ -- wrong order.+ duplicate n0@(NEIntMap k0 _ m0) =+ NEIntMap k0 n0+ . M.fromDistinctAscList+ . snd+ . L.mapAccumL go m0+ . M.toList+ $ m0+ where+ go m (k, v) = (m', (k, NEIntMap k v m'))+ where+ !m' = M.deleteMin m+ {-# INLINE duplicate #-}++-- | /O(n)/. Test if the internal map structure is valid.+valid :: NEIntMap a -> Bool+valid (NEIntMap k _ m) = all ((k <) . fst . fst) (M.minViewWithKey m)++-- | /O(log n)/. Insert new key and value into a map where keys are+-- /strictly greater than/ the new key. That is, the new key must be+-- /strictly less than/ all keys present in the 'IntMap'. /The precondition+-- is not checked./+--+-- At the moment this is simply an alias for @Data.IntSet.insert@, but it's+-- left here as a placeholder in case this eventually gets implemented in+-- a more efficient way.++-- TODO: implementation+insertMinMap :: Key -> a -> IntMap a -> IntMap a+insertMinMap = M.insert+{-# INLINEABLE insertMinMap #-}++-- | /O(log n)/. Insert new key and value into a map where keys are+-- /strictly less than/ the new key. That is, the new key must be+-- /strictly greater than/ all keys present in the 'IntMap'. /The+-- precondition is not checked./+--+-- At the moment this is simply an alias for @Data.IntSet.insert@, but it's+-- left here as a placeholder in case this eventually gets implemented in+-- a more efficient way.++-- TODO: implementation+insertMaxMap :: Key -> a -> IntMap a -> IntMap a+insertMaxMap = M.insert+{-# INLINEABLE insertMaxMap #-}
+ src/Data/IntMap/NonEmpty/Strict.hs view
@@ -0,0 +1,2072 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ViewPatterns #-}++-- |+-- Module : Data.IntMap.NonEmpty.Strict+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- = Non-Empty Finite Integer-Indexed Maps (strict interface)+--+-- The @'NEIntMap' v@ type represents a non-empty finite map (sometimes+-- called a dictionary) from integer keys to values of type @v@.+-- An 'NEIntMap' is strict in its keys and values.+--+-- See documentation for 'NEIntMap' for information on how to convert and+-- manipulate such non-empty maps.+--+-- This module essentially re-imports the API of "Data.IntMap.Strict" and its+-- 'IntMap' type, along with semantics and asymptotics. In most+-- situations, asymptotics are different only by a constant factor. In+-- some situations, asmyptotics are even better (constant-time instead of+-- log-time).+--+-- Because 'NEIntMap' is implemented using 'IntMap', all of the caveats of using+-- 'IntMap' apply (such as the limitation of the maximum size of maps).+--+-- All functions take non-empty maps as inputs. In situations where their+-- results can be guarunteed to also be non-empty, they also return+-- non-empty maps. In situations where their results could potentially be+-- empty, 'IntMap' is returned instead.+--+-- Some variants of functions (like 'alter'', 'alterF'', 'adjustMin',+-- 'adjustMax', 'adjustMinWithKey', 'adjustMaxWithKey') are provided in+-- a way restructured to preserve guaruntees of non-empty maps being+-- returned.+--+-- Some functions (like 'mapEither', 'partition', 'split')+-- have modified return types to account for possible configurations of+-- non-emptiness.+--+-- This module is intended to be imported qualified, to avoid name clashes with+-- "Prelude" and "Data.IntMap" functions:+--+-- > import qualified Data.IntMap.NonEmpty.Strict as NEIM+--+-- Note that all asmyptotics /O(f(n))/ in this module are actually+-- /O(min(W, f(n)))/, where @W@ is the number of bits in an 'Int' (32 or+-- 64). That is, if @f(n)@ is greater than @W@, all operations are+-- constant-time.+--+-- Import "Data.IntMap.NonEmpty.Lazy" for a variant lazy in values.+module Data.IntMap.NonEmpty.Strict (+ -- * Non-Empty IntMap Type+ NEIntMap,+ Key,++ -- ** Conversions between empty and non-empty maps+ pattern IsNonEmpty,+ pattern IsEmpty,+ nonEmptyMap,+ toMap,+ withNonEmpty,+ insertMap,+ insertMapWith,+ insertMapWithKey,+ insertMapMin,+ insertMapMax,+ unsafeFromMap,++ -- * Construction+ singleton,+ fromSet,++ -- ** From Unordered Lists+ fromList,+ fromListWith,+ fromListWithKey,++ -- ** From Ascending Lists+ fromAscList,+ fromAscListWith,+ fromAscListWithKey,+ fromDistinctAscList,++ -- * Insertion+ insert,+ insertWith,+ insertWithKey,+ insertLookupWithKey,++ -- * Deletion\/Update+ delete,+ deleteMaybe,+ adjust,+ adjustWithKey,+ update,+ updateWithKey,+ updateLookupWithKey,+ alter,+ alterF,+ alter',+ alterF',++ -- * Query++ -- ** Lookup+ lookup,+ (!?),+ (!),+ findWithDefault,+ member,+ notMember,+ lookupLT,+ lookupGT,+ lookupLE,+ lookupGE,++ -- ** Size+ size,++ -- * Combine++ -- ** Union+ union,+ unionMapLeft,+ unionMapRight,+ unionWith,+ unionMapWithLeft,+ unionMapWithRight,+ unionWithKey,+ unionMapWithKeyLeft,+ unionMapWithKeyRight,+ unions,+ unionsWith,++ -- ** Difference+ difference,+ (\\),+ differenceWith,+ differenceWithKey,++ -- ** Intersection+ intersection,+ intersectionWith,+ intersectionWithKey,+ -- -- ** Universal combining function+ -- , mergeWithKey++ -- * Traversal++ -- ** Map+ map,+ mapWithKey,+ traverseWithKey1,+ traverseWithKey,+ mapAccum,+ mapAccumWithKey,+ mapAccumRWithKey,+ mapKeys,+ mapKeysWith,+ mapKeysMonotonic,++ -- * Folds+ foldr,+ foldl,+ foldr1,+ foldl1,+ foldrWithKey,+ foldlWithKey,+ foldMapWithKey,++ -- ** Strict folds+ foldr',+ foldr1',+ foldl',+ foldl1',+ foldrWithKey',+ foldlWithKey',++ -- * Conversion+ elems,+ keys,+ assocs,+ keysSet,++ -- ** Lists+ toList,++ -- ** Ordered lists+ toAscList,+ toDescList,++ -- * Filter+ filter,+ filterWithKey,+ restrictKeys,+ withoutKeys,+ partition,+ partitionWithKey,+ mapMaybe,+ mapMaybeWithKey,+ mapEither,+ mapEitherWithKey,+ split,+ splitLookup,+ splitRoot,++ -- * Submap+ isSubmapOf,+ isSubmapOfBy,+ isProperSubmapOf,+ isProperSubmapOfBy,++ -- * Min\/Max+ findMin,+ findMax,+ deleteMin,+ deleteMax,+ deleteFindMin,+ deleteFindMax,+ updateMin,+ updateMax,+ adjustMin,+ adjustMax,+ updateMinWithKey,+ updateMaxWithKey,+ adjustMinWithKey,+ adjustMaxWithKey,+ minView,+ maxView,++ -- * Debugging+ valid,+) where++import Control.Applicative+import Data.Bifunctor+import qualified Data.Foldable as F+import Data.Functor.Identity+import Data.IntMap.Internal (IntMap (..))+import Data.IntMap.NonEmpty.Strict.Internal+import qualified Data.IntMap.Strict as M+import Data.IntSet (IntSet)+import qualified Data.IntSet as S+import Data.IntSet.NonEmpty.Internal (NEIntSet (..))+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE+import Data.Maybe hiding (mapMaybe)+import qualified Data.Maybe as Maybe+import Data.Semigroup.Foldable (Foldable1)+import qualified Data.Semigroup.Foldable as F1+import Data.These+import Prelude hiding (Foldable (..), filter, lookup, map)++-- | /O(1)/ match, /O(log n)/ usage of contents. The 'IsNonEmpty' and+-- 'IsEmpty' patterns allow you to treat a 'IntMap' as if it were either+-- a @'IsNonEmpty' n@ (where @n@ is a 'NEIntMap') or an 'IsEmpty'.+--+-- For example, you can pattern match on a 'IntMap':+--+-- @+-- myFunc :: 'IntMap' K X -> Y+-- myFunc ('IsNonEmpty' n) = -- here, the user provided a non-empty map, and @n@ is the 'NEIntMap'+-- myFunc 'IsEmpty' = -- here, the user provided an empty map.+-- @+--+-- Matching on @'IsNonEmpty' n@ means that the original 'IntMap' was /not/+-- empty, and you have a verified-non-empty 'NEIntMap' @n@ to use.+--+-- Note that patching on this pattern is /O(1)/. However, using the+-- contents requires a /O(log n)/ cost that is deferred until after the+-- pattern is matched on (and is not incurred at all if the contents are+-- never used).+--+-- A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides+-- complete coverage.+--+-- This is a bidirectional pattern, so you can use 'IsNonEmpty' to convert+-- a 'NEIntMap' back into a 'IntMap', obscuring its non-emptiness (see 'toMap').+pattern IsNonEmpty :: NEIntMap a -> IntMap a+pattern IsNonEmpty n <- (nonEmptyMap -> Just n)+ where+ IsNonEmpty n = toMap n++-- | /O(1)/. The 'IsNonEmpty' and 'IsEmpty' patterns allow you to treat+-- a 'IntMap' as if it were either a @'IsNonEmpty' n@ (where @n@ is+-- a 'NEIntMap') or an 'IsEmpty'.+--+-- Matching on 'IsEmpty' means that the original 'IntMap' was empty.+--+-- A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides+-- complete coverage.+--+-- This is a bidirectional pattern, so you can use 'IsEmpty' as an+-- expression, and it will be interpreted as 'Data.IntMap.empty'.+--+-- See 'IsNonEmpty' for more information.+pattern IsEmpty :: IntMap a+pattern IsEmpty <- (M.null -> True)+ where+ IsEmpty = M.empty++{-# COMPLETE IsNonEmpty, IsEmpty #-}++-- | /O(log n)/. Unsafe version of 'nonEmptyMap'. Coerces a 'IntMap' into an+-- 'NEIntMap', but is undefined (throws a runtime exception when evaluation is+-- attempted) for an empty 'IntMap'.+unsafeFromMap ::+ IntMap a ->+ NEIntMap a+unsafeFromMap = withNonEmpty e id+ where+ e = errorWithoutStackTrace "NEIntMap.unsafeFromMap: empty map"+{-# INLINE unsafeFromMap #-}++-- | /O(log n)/. Convert a 'IntMap' into an 'NEIntMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. If key is already present,+-- will overwrite the original value.+--+-- See 'insertMapMin' for a version that is constant-time if the new key is+-- /strictly smaller than/ all keys in the original map.+--+-- > insertMap 4 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])+-- > insertMap 4 "c" Data.IntMap.empty == singleton 4 "c"+insertMap :: Key -> a -> IntMap a -> NEIntMap a+insertMap k v = withNonEmpty (singleton k v) (insert k v)+{-# INLINE insertMap #-}++-- | /O(log n)/. Convert a 'IntMap' into an 'NEIntMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. Uses a combining function+-- with the new value as the first argument if the key is already present.+--+-- > insertMapWith (++) 4 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])+-- > insertMapWith (++) 5 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"ca")])+insertMapWith ::+ (a -> a -> a) ->+ Key ->+ a ->+ IntMap a ->+ NEIntMap a+insertMapWith f k v = withNonEmpty (singleton k v) (insertWith f k v)+{-# INLINE insertMapWith #-}++-- | /O(log n)/. Convert a 'IntMap' into an 'NEIntMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. Uses a combining function+-- with the key and new value as the first and second arguments if the key+-- is already present.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "5:xxx|a")])+-- > insertWithKey f 7 "xxx" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+-- > insertWithKey f 5 "xxx" Data.IntMap.empty == singleton 5 "xxx"+insertMapWithKey ::+ (Key -> a -> a -> a) ->+ Key ->+ a ->+ IntMap a ->+ NEIntMap a+insertMapWithKey f k v = withNonEmpty (singleton k v) (insertWithKey f k v)+{-# INLINE insertMapWithKey #-}++-- | /O(1)/ Convert a 'IntMap' into an 'NEIntMap' by adding a key-value pair+-- where the key is /strictly less than/ all keys in the input map. The+-- keys in the original map must all be /strictly greater than/ the new+-- key. /The precondition is not checked./+--+-- > insertMapMin 2 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((2,"c") :| [(3,"b"), (5,"a")])+-- > valid (insertMapMin 2 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == True+-- > valid (insertMapMin 7 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False+-- > valid (insertMapMin 3 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False+insertMapMin ::+ Key ->+ a ->+ IntMap a ->+ NEIntMap a+insertMapMin = NEIntMap+{-# INLINE insertMapMin #-}++-- | /O(log n)/ Convert a 'IntMap' into an 'NEIntMap' by adding a key-value pair+-- where the key is /strictly greater than/ all keys in the input map. The+-- keys in the original map must all be /strictly less than/ the new+-- key. /The precondition is not checked./+--+-- At the current moment, this is identical simply 'insertMap'; however,+-- it is left both for consistency and as a placeholder for a future+-- version where optimizations are implemented to allow for a faster+-- implementation.+--+-- > insertMap 7 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"a"), (7,"c")])++-- these currently are all valid, but shouldn't be+-- > valid (insertMap 7 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == True+-- > valid (insertMap 2 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False+-- > valid (insertMap 5 "c" (Data.IntMap.fromList [(5,"a"), (3,"b")])) == False+insertMapMax ::+ Key ->+ a ->+ IntMap a ->+ NEIntMap a+insertMapMax k v = withNonEmpty (singleton k v) go+ where+ go (NEIntMap k0 v0 m0) = NEIntMap k0 v0 . insertMaxMap k v $ m0+{-# INLINE insertMapMax #-}++-- | /O(n)/. Build a non-empty map from a non-empty set of keys and+-- a function which for each key computes its value.+--+-- > fromSet (\k -> replicate k 'a') (Data.Set.NonEmpty.fromList (3 :| [5])) == fromList ((5,"aaaaa") :| [(3,"aaa")])+fromSet ::+ (Key -> a) ->+ NEIntSet ->+ NEIntMap a+fromSet f (NEIntSet k ks) = NEIntMap k (f k) (M.fromSet f ks)+{-# INLINE fromSet #-}++-- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs+-- with a combining function. See also 'fromAscListWith'.+--+-- > fromListWith (++) ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "ab") :| [(5, "aba")])+fromListWith ::+ (a -> a -> a) ->+ NonEmpty (Key, a) ->+ NEIntMap a+fromListWith f = fromListWithKey (const f)+{-# INLINE fromListWith #-}++-- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs+-- with a combining function. See also 'fromAscListWithKey'.+--+-- > let f k a1 a2 = (show k) ++ a1 ++ a2+-- > fromListWithKey f ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "3ab") :| [(5, "5a5ba")])+fromListWithKey ::+ (Key -> a -> a -> a) ->+ NonEmpty (Key, a) ->+ NEIntMap a+fromListWithKey f ((k0, v0) :| xs) = F.foldl' go (singleton k0 v0) xs+ where+ go m (k, v) = insertWithKey f k v m+ {-# INLINE go #-}+{-# INLINE fromListWithKey #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time.+-- /The precondition (input list is ascending) is not checked./+--+-- > fromAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])+-- > fromAscList ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "b")])+-- > valid (fromAscList ((3,"b") :| [(5,"a"), (5,"b")])) == True+-- > valid (fromAscList ((5,"a") :| [(3,"b"), (5,"b")])) == False+fromAscList ::+ NonEmpty (Key, a) ->+ NEIntMap a+fromAscList = fromDistinctAscList . combineEq+{-# INLINE fromAscList #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is ascending) is not checked./+--+-- > fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "ba")])+-- > valid (fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b"))]) == True+-- > valid (fromAscListWith (++) ((5,"a") :| [(3,"b"), (5,"b"))]) == False+fromAscListWith ::+ (a -> a -> a) ->+ NonEmpty (Key, a) ->+ NEIntMap a+fromAscListWith f = fromAscListWithKey (const f)+{-# INLINE fromAscListWith #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is ascending) is not checked./+--+-- > let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2+-- > fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")]) == fromList ((3, "b") :| [(5, "5:b5:ba")])+-- > valid (fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")])) == True+-- > valid (fromAscListWithKey f ((5,"a") :| [(3,"b"), (5,"b"), (5,"b")])) == False+fromAscListWithKey ::+ (Key -> a -> a -> a) ->+ NonEmpty (Key, a) ->+ NEIntMap a+fromAscListWithKey f = fromDistinctAscList . combineEqWith f+{-# INLINE fromAscListWithKey #-}++-- | /O(n)/. Build a map from an ascending non-empty list of distinct+-- elements in linear time. /The precondition is not checked./+--+-- > fromDistinctAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])+-- > valid (fromDistinctAscList ((3,"b") :| [(5,"a")])) == True+-- > valid (fromDistinctAscList ((3,"b") :| [(5,"a"), (5,"b")])) == False+fromDistinctAscList :: NonEmpty (Key, a) -> NEIntMap a+fromDistinctAscList ((k, v) :| xs) =+ insertMapMin k v+ . M.fromDistinctAscList+ $ xs+{-# INLINE fromDistinctAscList #-}++-- | /O(log n)/. Insert a new key and value in the map.+-- If the key is already present in the map, the associated value is+-- replaced with the supplied value. 'insert' is equivalent to+-- @'insertWith' 'const'@.+--+-- See 'insertMap' for a version where the first argument is a 'IntMap'.+--+-- > insert 5 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'x')])+-- > insert 7 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'a'), (7, 'x')])+insert ::+ Key ->+ a ->+ NEIntMap a ->+ NEIntMap a+insert k v n@(NEIntMap k0 v0 m) = case compare k k0 of+ LT -> NEIntMap k v . toMap $ n+ EQ -> NEIntMap k v m+ GT -> NEIntMap k0 v0 . M.insert k v $ m+{-# INLINE insert #-}++-- | /O(log n)/. Insert with a function, combining key, new value and old+-- value. @'insertWithKey' f key value mp@ will insert the pair (key,+-- value) into @mp@ if key does not exist in the map. If the key does+-- exist, the function will insert the pair @(key,f key new_value+-- old_value)@. Note that the key passed to f is the same key passed to+-- 'insertWithKey'.+--+-- See 'insertMapWithKey' for a version where the first argument is a 'IntMap'.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:xxx|a")])+-- > insertWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+insertWithKey ::+ (Key -> a -> a -> a) ->+ Key ->+ a ->+ NEIntMap a ->+ NEIntMap a+insertWithKey f k v n@(NEIntMap k0 v0 m) = case compare k k0 of+ LT -> NEIntMap k v . toMap $ n+ EQ -> NEIntMap k (f k v v0) m+ GT -> NEIntMap k0 v0 $ M.insertWithKey f k v m+{-# INLINE insertWithKey #-}++-- | /O(log n)/. Combines insert operation with old value retrieval. The+-- expression (@'insertLookupWithKey' f k x map@) is a pair where the first+-- element is equal to (@'lookup' k map@) and the second element equal to+-- (@'insertWithKey' f k x map@).+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertLookupWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "5:xxx|a")]))+-- > insertLookupWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "xxx")]))+--+-- This is how to define @insertLookup@ using @insertLookupWithKey@:+--+-- > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t+-- > insertLookup 5 "x" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "x")]))+-- > insertLookup 7 "x" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "x")]))+insertLookupWithKey ::+ (Key -> a -> a -> a) ->+ Key ->+ a ->+ NEIntMap a ->+ (Maybe a, NEIntMap a)+insertLookupWithKey f k v n@(NEIntMap k0 v0 m) = case compare k k0 of+ LT -> (Nothing, NEIntMap k v . toMap $ n)+ EQ -> (Just v, NEIntMap k (f k v v0) m)+ GT -> NEIntMap k0 v0 <$> M.insertLookupWithKey f k v m+{-# INLINE insertLookupWithKey #-}++-- | /O(log n)/. Delete a key and its value from the non-empty map.+-- A potentially empty map ('IntMap') is returned, since this might delete the+-- last item in the 'NEIntMap'. When the key is not a member of the map, is+-- equivalent to 'toMap'.+--+-- > delete 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"+-- > delete 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.Singleton [(3, "b"), (5, "a")]+delete :: Key -> NEIntMap a -> IntMap a+delete k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> toMap n+ EQ -> m+ GT -> insertMinMap k0 v . M.delete k $ m+{-# INLINE delete #-}++-- | /O(log n)/. Delete a key and its value from the non-empty map, returning+-- 'Nothing' if the result would be empty.+--+-- This is more efficient than @'nonEmptyMap' . 'delete' k@ because it avoids+-- converting the known-minimum representation back through 'IntMap' when the+-- deleted key is not the minimum.+--+-- @since 0.3.6.0+deleteMaybe :: Key -> NEIntMap a -> Maybe (NEIntMap a)+deleteMaybe k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> Just n+ EQ -> nonEmptyMap m+ GT -> Just . NEIntMap k0 v . M.delete k $ m+{-# INLINE deleteMaybe #-}++-- | /O(log n)/. Update a value at a specific key with the result of the+-- provided function. When the key is not a member of the map, the original+-- map is returned.+--+-- > adjust ("new " ++) 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "new a")])+-- > adjust ("new " ++) 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])+adjust ::+ (a -> a) ->+ Key ->+ NEIntMap a ->+ NEIntMap a+adjust f = adjustWithKey (const f)+{-# INLINE adjust #-}++-- | /O(log n)/. Adjust a value at a specific key. When the key is not+-- a member of the map, the original map is returned.+--+-- > let f key x = (show key) ++ ":new " ++ x+-- > adjustWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:new a")])+-- > adjustWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])+adjustWithKey ::+ (Key -> a -> a) ->+ Key ->+ NEIntMap a ->+ NEIntMap a+adjustWithKey f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> n+ EQ -> NEIntMap k0 (f k0 v) m+ GT -> NEIntMap k0 v . M.adjustWithKey f k $ m+{-# INLINE adjustWithKey #-}++-- | /O(log n)/. The expression (@'update' f k map@) updates the value @x@+-- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is+-- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.+--+-- Returns a potentially empty map ('IntMap'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEIntMap'.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > update f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "new a")]+-- > update f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a")]+-- > update f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+update ::+ (a -> Maybe a) ->+ Key ->+ NEIntMap a ->+ IntMap a+update f = updateWithKey (const f)+{-# INLINE update #-}++-- | /O(log n)/. The expression (@'updateWithKey' f k map@) updates the+-- value @x@ at @k@ (if it is in the map). If (@f k x@) is 'Nothing',+-- the element is deleted. If it is (@'Just' y@), the key @k@ is bound+-- to the new value @y@.+--+-- Returns a potentially empty map ('IntMap'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEIntMap'.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "5:new a")]+-- > updateWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a")]+-- > updateWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+updateWithKey ::+ (Key -> a -> Maybe a) ->+ Key ->+ NEIntMap a ->+ IntMap a+updateWithKey f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> toMap n+ EQ -> maybe m (flip (insertMinMap k0) m) . f k0 $ v+ GT -> insertMinMap k0 v . M.updateWithKey f k $ m+{-# INLINE updateWithKey #-}++-- | /O(min(n,W))/. Lookup and update.+-- The function returns original value, if it is updated.+-- This is different behavior than @Data.Map.NonEmpty.updateLookupWithKey@.+-- Returns the original key value if the map entry is deleted.+--+-- Returns a potentially empty map ('IntMap') in the case that we delete+-- the final key of a singleton map.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateLookupWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == (Just "5:new a", Data.IntMap.fromList ((3, "b") :| [(5, "5:new a")]))+-- > updateLookupWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == (Nothing, Data.IntMap.fromList ((3, "b") :| [(5, "a")]))+-- > updateLookupWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == (Just "b", Data.IntMap.singleton 5 "a")+updateLookupWithKey ::+ (Key -> a -> Maybe a) ->+ Key ->+ NEIntMap a ->+ (Maybe a, IntMap a)+updateLookupWithKey f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> (Nothing, toMap n)+ EQ ->+ let u = f k0 v+ in (Just v, maybe m (flip (insertMinMap k0) m) u)+ GT -> fmap (insertMinMap k0 v) . M.updateLookupWithKey f k $ m+{-# INLINE updateLookupWithKey #-}++-- | /O(log n)/. The expression (@'alter' f k map@) alters the value @x@ at+-- @k@, or absence thereof. 'alter' can be used to insert, delete, or+-- update a value in a 'IntMap'. In short : @Data.IntMap.lookup k ('alter'+-- f k m) = f ('lookup' k m)@.+--+-- Returns a potentially empty map ('IntMap'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEIntMap'.+--+-- See 'alterF'' for a version that disallows deletion, and so therefore+-- can return 'NEIntMap'.+--+-- > let f _ = Nothing+-- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a")]+-- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"+-- >+-- > let f _ = Just "c"+-- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "a"), (7, "c")]+-- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "c")]+alter ::+ (Maybe a -> Maybe a) ->+ Key ->+ NEIntMap a ->+ IntMap a+alter f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> maybe id (insertMinMap k) (f Nothing) (toMap n)+ EQ -> maybe id (insertMinMap k0) (f (Just v)) m+ GT -> insertMinMap k0 v . M.alter f k $ m+{-# INLINE alter #-}++-- | /O(log n)/. The expression (@'alterF' f k map@) alters the value @x@+-- at @k@, or absence thereof. 'alterF' can be used to inspect, insert,+-- delete, or update a value in a 'IntMap'. In short: @Data.IntMap.lookup+-- k \<$\> 'alterF' f k m = f ('lookup' k m)@.+--+-- Example:+--+-- @+-- interactiveAlter :: Int -> NEIntMap Int String -> IO (IntMap Int String)+-- interactiveAlter k m = alterF f k m where+-- f Nothing = do+-- putStrLn $ show k +++-- " was not found in the map. Would you like to add it?"+-- getUserResponse1 :: IO (Maybe String)+-- f (Just old) = do+-- putStrLn $ "The key is currently bound to " ++ show old +++-- ". Would you like to change or delete it?"+-- getUserResponse2 :: IO (Maybe String)+-- @+--+-- Like @Data.IntMap.alterF@ for 'IntMap', 'alterF' can be considered+-- to be a unifying generalization of 'lookup' and 'delete'; however, as+-- a constrast, it cannot be used to implement 'insert', because it must+-- return a 'IntMap' instead of an 'NEIntMap' (because the function might delete+-- the final item in the 'NEIntMap'). When used with trivial functors like+-- 'Identity' and 'Const', it is often slightly slower than+-- specialized 'lookup' and 'delete'. However, when the functor is+-- non-trivial and key comparison is not particularly cheap, it is the+-- fastest way.+--+-- See 'alterF'' for a version that disallows deletion, and so therefore+-- can return 'NEIntMap' and be used to implement 'insert'+--+-- Note on rewrite rules:+--+-- This module includes GHC rewrite rules to optimize 'alterF' for+-- the 'Const' and 'Identity' functors. In general, these rules+-- improve performance. The sole exception is that when using+-- 'Identity', deleting a key that is already absent takes longer+-- than it would without the rules. If you expect this to occur+-- a very large fraction of the time, you might consider using a+-- private copy of the 'Identity' type.+--+-- Note: Unlike @Data.IntMap.alterF@ for 'IntMap', 'alterF' is /not/ a flipped+-- version of the 'Control.Lens.At.at' combinator from "Control.Lens.At".+-- However, it match the shape expected from most functions expecting+-- lenses, getters, and setters, so can be thought of as a "psuedo-lens",+-- with virtually the same practical applications as a legitimate lens.+alterF ::+ Functor f =>+ (Maybe a -> f (Maybe a)) ->+ Key ->+ NEIntMap a ->+ f (IntMap a)+alterF f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> flip (maybe id (insertMinMap k)) (toMap n) <$> f Nothing+ EQ -> flip (maybe id (insertMinMap k0)) m <$> f (Just v)+ GT -> insertMinMap k0 v <$> M.alterF f k m+{-# INLINEABLE [2] alterF #-}++-- if f ~ Const b, it's a lookup+{-# RULES+"alterF/Const" forall k (f :: Maybe a -> Const b (Maybe a)).+ alterF f k =+ Const . getConst . f . lookup k+ #-}++-- if f ~ Identity, it's an 'alter'+{-# RULES+"alterF/Identity" forall k (f :: Maybe a -> Identity (Maybe a)).+ alterF f k =+ Identity . alter (runIdentity . f) k+ #-}++-- | /O(log n)/. Variant of 'alter' that disallows deletion. Allows us to+-- guarantee that the result is also a non-empty IntMap.+alter' ::+ (Maybe a -> a) ->+ Key ->+ NEIntMap a ->+ NEIntMap a+alter' f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> NEIntMap k (f Nothing) . toMap $ n+ EQ -> NEIntMap k0 (f (Just v)) m+ GT -> NEIntMap k0 v . M.alter (Just . f) k $ m+{-# INLINE alter' #-}++-- | /O(log n)/. Variant of 'alterF' that disallows deletion. Allows us to+-- guarantee that the result is also a non-empty IntMap.+--+-- Like @Data.IntMap.alterF@ for 'IntMap', can be used to generalize and unify+-- 'lookup' and 'insert'. However, because it disallows deletion, it+-- cannot be used to implement 'delete'.+--+-- See 'alterF' for usage information and caveats.+--+-- Note: Neither 'alterF' nor 'alterF'' can be considered flipped versions+-- of the 'Control.Lens.At.at' combinator from "Control.Lens.At". However,+-- this can match the shape expected from most functions expecting lenses,+-- getters, and setters, so can be thought of as a "psuedo-lens", with+-- virtually the same practical applications as a legitimate lens.+--+-- __WARNING__: The rewrite rule for 'Identity' exposes an inconsistency in+-- undefined behavior for "Data.IntMap". @Data.IntMap.alterF@ will actually+-- /maintain/ the original key in the map when used with 'Identity';+-- however, @Data.IntMap.insertWith@ will /replace/ the orginal key in the+-- map. The rewrite rule for 'alterF'' has chosen to be faithful to+-- @Data.IntMap.insertWith@, and /not/ @Data.IntMap.alterF@, for the sake of+-- a cleaner implementation.+alterF' ::+ Functor f =>+ (Maybe a -> f a) ->+ Key ->+ NEIntMap a ->+ f (NEIntMap a)+alterF' f k n@(NEIntMap k0 v m) = case compare k k0 of+ LT -> flip (NEIntMap k) (toMap n) <$> f Nothing+ EQ -> flip (NEIntMap k0) m <$> f (Just v)+ GT -> NEIntMap k0 v <$> M.alterF (fmap Just . f) k m+{-# INLINEABLE [2] alterF' #-}++-- if f ~ Const b, it's a lookup+{-# RULES+"alterF'/Const" forall k (f :: Maybe a -> Const b a).+ alterF' f k =+ Const . getConst . f . lookup k+ #-}++-- if f ~ Identity, it's an insertWith+{-# RULES+"alterF'/Identity" forall k (f :: Maybe a -> Identity a).+ alterF' f k =+ Identity . insertWith (\_ -> runIdentity . f . Just) k (runIdentity (f Nothing))+ #-}++-- | /O(log n)/. Lookup the value at a key in the map.+--+-- The function will return the corresponding value as @('Just' value)@,+-- or 'Nothing' if the key isn't in the map.+--+-- An example of using @lookup@:+--+-- > import Prelude hiding (lookup)+-- > import Data.Map.NonEmpty+-- >+-- > employeeDept = fromList (("John","Sales") :| [("Bob","IT")])+-- > deptCountry = fromList (("IT","USA") :| [("Sales","France")])+-- > countryCurrency = fromList (("USA", "Dollar") :| [("France", "Euro")])+-- >+-- > employeeCurrency :: String -> Maybe String+-- > employeeCurrency name = do+-- > dept <- lookup name employeeDept+-- > country <- lookup dept deptCountry+-- > lookup country countryCurrency+-- >+-- > main = do+-- > putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))+-- > putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))+--+-- The output of this program:+--+-- > John's currency: Just "Euro"+-- > Pete's currency: Nothing+lookup ::+ Key ->+ NEIntMap a ->+ Maybe a+lookup k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just v+ GT -> M.lookup k m+{-# INLINE lookup #-}++-- | /O(log n)/. Find the value at a key. Returns 'Nothing' when the+-- element can not be found.+--+-- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 1 == Nothing+-- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 5 == Just 'a'+(!?) :: NEIntMap a -> Key -> Maybe a+(!?) = flip lookup+{-# INLINE (!?) #-}++-- | /O(log n)/. Find the value at a key. Calls 'error' when the element+-- can not be found.+--+-- > fromList ((5,'a') :| [(3,'b')]) ! 1 Error: element not in the map+-- > fromList ((5,'a') :| [(3,'b')]) ! 5 == 'a'+(!) :: NEIntMap a -> Key -> a+(!) m k = fromMaybe e $ m !? k+ where+ e = error "NEIntMap.!: given key is not an element in the map"+{-# INLINE (!) #-}++infixl 9 !?+infixl 9 !++-- | /O(log n)/. The expression @('findWithDefault' def k map)@ returns+-- the value at key @k@ or returns default value @def@+-- when the key is not in the map.+--+-- > findWithDefault 'x' 1 (fromList ((5,'a') :| [(3,'b')])) == 'x'+-- > findWithDefault 'x' 5 (fromList ((5,'a') :| [(3,'b')])) == 'a'+findWithDefault ::+ a ->+ Key ->+ NEIntMap a ->+ a+findWithDefault def k (NEIntMap k0 v m) = case compare k k0 of+ LT -> def+ EQ -> v+ GT -> M.findWithDefault def k m+{-# INLINE findWithDefault #-}++-- | /O(log n)/. Is the key a member of the map? See also 'notMember'.+--+-- > member 5 (fromList ((5,'a') :| [(3,'b')])) == True+-- > member 1 (fromList ((5,'a') :| [(3,'b')])) == False+member :: Key -> NEIntMap a -> Bool+member k (NEIntMap k0 _ m) = case compare k k0 of+ LT -> False+ EQ -> True+ GT -> M.member k m+{-# INLINE member #-}++-- | /O(log n)/. Is the key not a member of the map? See also 'member'.+--+-- > notMember 5 (fromList ((5,'a') :| [(3,'b')])) == False+-- > notMember 1 (fromList ((5,'a') :| [(3,'b')])) == True+notMember :: Key -> NEIntMap a -> Bool+notMember k (NEIntMap k0 _ m) = case compare k k0 of+ LT -> True+ EQ -> False+ GT -> M.notMember k m+{-# INLINE notMember #-}++-- | /O(log n)/. Find largest key smaller than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupLT 3 (fromList ((3,'a') :| [(5,'b')])) == Nothing+-- > lookupLT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+lookupLT :: Key -> NEIntMap a -> Maybe (Key, a)+lookupLT k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Nothing+ GT -> M.lookupLT k m <|> Just (k0, v)+{-# INLINE lookupLT #-}++-- | /O(log n)/. Find smallest key greater than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupGT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+-- > lookupGT 5 (fromList ((3,'a') :| [(5,'b')])) == Nothing+lookupGT :: Key -> NEIntMap a -> Maybe (Key, a)+lookupGT k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Just (k0, v)+ EQ -> M.lookupMin m+ GT -> M.lookupGT k m+{-# INLINE lookupGT #-}++-- | /O(log n)/. Find largest key smaller or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupLE 2 (fromList ((3,'a') :| [(5,'b')])) == Nothing+-- > lookupLE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+-- > lookupLE 5 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+lookupLE :: Key -> NEIntMap a -> Maybe (Key, a)+lookupLE k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just (k0, v)+ GT -> M.lookupLE k m <|> Just (k0, v)+{-# INLINE lookupLE #-}++-- | /O(log n)/. Find smallest key greater or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupGE 3 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+-- > lookupGE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+-- > lookupGE 6 (fromList ((3,'a') :| [(5,'b')])) == Nothing+lookupGE :: Key -> NEIntMap a -> Maybe (Key, a)+lookupGE k (NEIntMap k0 v m) = case compare k k0 of+ LT -> Just (k0, v)+ EQ -> Just (k0, v)+ GT -> M.lookupGE k m+{-# INLINE lookupGE #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union with a combining function.+--+-- > unionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "aA"), (7, "C")])+unionWith ::+ (a -> a -> a) ->+ NEIntMap a ->+ NEIntMap a ->+ NEIntMap a+unionWith f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEIntMap k1 v1 . M.unionWith f m1 . toMap $ n2+ EQ -> NEIntMap k1 (f v1 v2) . M.unionWith f m1 $ m2+ GT -> NEIntMap k2 v2 . M.unionWith f (toMap n1) $ m2+{-# INLINE unionWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a possibly-empty+-- 'IntMap' and a non-empty map.+--+-- @since 0.3.6.0+unionMapLeft :: IntMap a -> NEIntMap a -> NEIntMap a+unionMapLeft m n = withNonEmpty n (`union` n) m+{-# INLINE unionMapLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a non-empty map and a+-- possibly-empty 'IntMap'.+--+-- @since 0.3.6.0+unionMapRight :: NEIntMap a -> IntMap a -> NEIntMap a+unionMapRight n = withNonEmpty n (union n)+{-# INLINE unionMapRight #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'IntMap' and a+-- non-empty map with a combining function.+--+-- @since 0.3.6.0+unionMapWithLeft :: (a -> a -> a) -> IntMap a -> NEIntMap a -> NEIntMap a+unionMapWithLeft f m n = withNonEmpty n (\m' -> unionWith f m' n) m+{-# INLINE unionMapWithLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a+-- possibly-empty 'IntMap' with a combining function.+--+-- @since 0.3.6.0+unionMapWithRight :: (a -> a -> a) -> NEIntMap a -> IntMap a -> NEIntMap a+unionMapWithRight f n = withNonEmpty n (unionWith f n)+{-# INLINE unionMapWithRight #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- Union with a combining function, given the matching key.+--+-- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value+-- > unionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "5:a|A"), (7, "C")])+unionWithKey ::+ (Key -> a -> a -> a) ->+ NEIntMap a ->+ NEIntMap a ->+ NEIntMap a+unionWithKey f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEIntMap k1 v1 . M.unionWithKey f m1 . toMap $ n2+ EQ -> NEIntMap k1 (f k1 v1 v2) . M.unionWithKey f m1 $ m2+ GT -> NEIntMap k2 v2 . M.unionWithKey f (toMap n1) $ m2+{-# INLINE unionWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'IntMap' and a+-- non-empty map with a combining function, given the matching key.+--+-- @since 0.3.6.0+unionMapWithKeyLeft ::+ (Key -> a -> a -> a) ->+ IntMap a ->+ NEIntMap a ->+ NEIntMap a+unionMapWithKeyLeft f m n = withNonEmpty n (\m' -> unionWithKey f m' n) m+{-# INLINE unionMapWithKeyLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a+-- possibly-empty 'IntMap' with a combining function, given the matching key.+--+-- @since 0.3.6.0+unionMapWithKeyRight ::+ (Key -> a -> a -> a) ->+ NEIntMap a ->+ IntMap a ->+ NEIntMap a+unionMapWithKeyRight f n = withNonEmpty n (unionWithKey f n)+{-# INLINE unionMapWithKeyRight #-}++-- | The union of a non-empty list of maps, with a combining operation:+-- (@'unionsWith' f == 'Data.Foldable.foldl1' ('unionWith' f)@).+--+-- > unionsWith (++) (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])+-- > == fromList ((3, "bB3") :| [(5, "aAA3"), (7, "C")])+unionsWith ::+ Foldable1 f =>+ (a -> a -> a) ->+ f (NEIntMap a) ->+ NEIntMap a+unionsWith f (F1.toNonEmpty -> (m :| ms)) = F.foldl' (unionWith f) m ms+{-# INLINE unionsWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Difference of two maps.+-- Return elements of the first map not existing in the second map.+--+-- Returns a potentially empty map ('IntMap'), in case the first map is+-- a subset of the second map.+--+-- > difference (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 3 "b"+difference ::+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+difference n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 _ m2) = case compare k1 k2 of+ -- k1 is not in n2, so cannot be deleted+ LT -> insertMinMap k1 v1 $ m1 `M.difference` toMap n2+ -- k2 deletes k1, and only k1+ EQ -> m1 `M.difference` m2+ -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.+ GT -> toMap n1 `M.difference` m2+{-# INLINE difference #-}++-- | Same as 'difference'.+(\\) ::+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+(\\) = difference+{-# INLINE (\\) #-}++-- | /O(n+m)/. Difference with a combining function.+-- When two equal keys are+-- encountered, the combining function is applied to the values of these keys.+-- 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@.+--+-- Returns a potentially empty map ('IntMap'), in case the first map is+-- a subset of the second map and the function returns 'Nothing' for every+-- pair.+--+-- > let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing+-- > differenceWith f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (7, "C")]))+-- > == Data.IntMap.singleton 3 "b:B"+differenceWith ::+ (a -> b -> Maybe a) ->+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+differenceWith f = differenceWithKey (const f)+{-# INLINE differenceWith #-}++-- | /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@.+--+-- Returns a potentially empty map ('IntMap'), in case the first map is+-- a subset of the second map and the function returns 'Nothing' for every+-- pair.+--+-- > let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing+-- > differenceWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (10, "C")]))+-- > == Data.IntMap.singleton 3 "3:b|B"+differenceWithKey ::+ (Key -> a -> b -> Maybe a) ->+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+differenceWithKey f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ -- k1 is not in n2, so cannot be deleted+ LT -> insertMinMap k1 v1 $ M.differenceWithKey f m1 (toMap n2)+ -- k2 deletes k1, and only k1+ EQ -> maybe id (insertMinMap k1) (f k1 v1 v2) (M.differenceWithKey f m1 m2)+ -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.+ GT -> M.differenceWithKey f (toMap n1) m2+{-# INLINE differenceWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection of two maps.+-- Return data in the first map for the keys existing in both maps.+-- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).+--+-- Returns a potentially empty map ('IntMap'), in case the two maps share no+-- keys in common.+--+-- > intersection (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 5 "a"+intersection ::+ NEIntMap a ->+ NEIntMap b ->+ IntMap a+intersection n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 _ m2) = case compare k1 k2 of+ -- k1 is not in n2+ LT -> m1 `M.intersection` toMap n2+ -- k1 and k2 are a part of the result+ EQ -> insertMinMap k1 v1 $ m1 `M.intersection` m2+ -- k2 is not in n1+ GT -> toMap n1 `M.intersection` m2+{-# INLINE intersection #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.+--+-- Returns a potentially empty map ('IntMap'), in case the two maps share no+-- keys in common.+--+-- > intersectionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 5 "aA"+intersectionWith ::+ (a -> b -> c) ->+ NEIntMap a ->+ NEIntMap b ->+ IntMap c+intersectionWith f = intersectionWithKey (const f)+{-# INLINE intersectionWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.+--+-- Returns a potentially empty map ('IntMap'), in case the two maps share no+-- keys in common.+--+-- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar+-- > intersectionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.IntMap.singleton 5 "5:a|A"+intersectionWithKey ::+ (Key -> a -> b -> c) ->+ NEIntMap a ->+ NEIntMap b ->+ IntMap c+intersectionWithKey f n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ -- k1 is not in n2+ LT -> M.intersectionWithKey f m1 (toMap n2)+ -- k1 and k2 are a part of the result+ EQ -> insertMinMap k1 (f k1 v1 v2) $ M.intersectionWithKey f m1 m2+ -- k2 is not in n1+ GT -> M.intersectionWithKey f (toMap n1) m2+{-# INLINE intersectionWithKey #-}++-- | /O(n)/. IntMap a function over all values in the map.+--+-- > let f key x = (show key) ++ ":" ++ x+-- > mapWithKey f (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "3:b") :| [(5, "5:a")])+mapWithKey :: (Key -> a -> b) -> NEIntMap a -> NEIntMap b+mapWithKey f (NEIntMap k v m) = NEIntMap k (f k v) (M.mapWithKey f m)+{-# NOINLINE [1] mapWithKey #-}++{-# RULES+"mapWithKey/mapWithKey" forall f g xs.+ mapWithKey f (mapWithKey g xs) =+ mapWithKey (\k a -> f k (g k a)) xs+"mapWithKey/map" forall f g xs.+ mapWithKey f (map g xs) =+ mapWithKey (\k a -> f k (g a)) xs+"map/mapWithKey" forall f g xs.+ map f (mapWithKey g xs) =+ mapWithKey (\k a -> f (g k a)) xs+ #-}++-- | /O(n)/. The function 'mapAccum' threads an accumulating argument+-- through the map in ascending order of keys.+--+-- > let f a b = (a ++ b, b ++ "X")+-- > mapAccum f "Everything: " (fromList ((5,"a") :| [(3,"b")])) == ("Everything: ba", fromList ((3, "bX") :| [(5, "aX")]))+mapAccum ::+ (a -> b -> (a, c)) ->+ a ->+ NEIntMap b ->+ (a, NEIntMap c)+mapAccum f = mapAccumWithKey (\x _ -> f x)+{-# INLINE mapAccum #-}++-- | /O(n)/. The function 'mapAccumWithKey' threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")+-- > mapAccumWithKey f "Everything:" (fromList ((5,"a") :| [(3,"b")])) == ("Everything: 3-b 5-a", fromList ((3, "bX") :| [(5, "aX")]))+mapAccumWithKey ::+ (a -> Key -> b -> (a, c)) ->+ a ->+ NEIntMap b ->+ (a, NEIntMap c)+mapAccumWithKey f z0 (NEIntMap k v m) = (z2, NEIntMap k v' m')+ where+ ~(z1, v') = f z0 k v+ ~(z2, m') = M.mapAccumWithKey f z1 m+{-# INLINE mapAccumWithKey #-}++-- | /O(n)/. The function 'mapAccumRWithKey' threads an accumulating+-- argument through the map in descending order of keys.+mapAccumRWithKey ::+ (a -> Key -> b -> (a, c)) ->+ a ->+ NEIntMap b ->+ (a, NEIntMap c)+mapAccumRWithKey f z0 (NEIntMap k v m) = (z2, NEIntMap k v' m')+ where+ ~(z1, m') = M.mapAccumRWithKey f z0 m+ ~(z2, v') = f z1 k v+{-# INLINE mapAccumRWithKey #-}++-- | /O(n*log n)/.+-- @'mapKeys' 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 value at the greatest of the+-- original keys is retained.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeys (+ 1) (fromList ((5,"a") :| [(3,"b")])) == fromList ((4, "b") :| [(6, "a")])+-- > mapKeys (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "c"+-- > mapKeys (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "c"+mapKeys ::+ (Key -> Key) ->+ NEIntMap a ->+ NEIntMap a+mapKeys f (NEIntMap k0 v0 m) =+ fromListWith const+ . ((f k0, v0) :|)+ . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []+ $ m+{-# INLINEABLE mapKeys #-}++-- | /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@. The value at the greater of the two original keys+-- is used as the first argument to @c@.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeysWith (++) (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "cdab"+-- > mapKeysWith (++) (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "cdab"+mapKeysWith ::+ (a -> a -> a) ->+ (Key -> Key) ->+ NEIntMap a ->+ NEIntMap a+mapKeysWith c f (NEIntMap k0 v0 m) =+ fromListWith c+ . ((f k0, v0) :|)+ . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []+ $ m+{-# INLINEABLE mapKeysWith #-}++-- | /O(n)/.+-- @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@+-- is strictly monotonic.+-- 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]+-- > ==> mapKeysMonotonic f s == mapKeys f s+-- > where ls = keys s+--+-- This means that @f@ maps distinct original keys to distinct resulting keys.+-- This function has better performance than 'mapKeys'.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")])) == fromList ((6, "b") :| [(10, "a")])+-- > valid (mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")]))) == True+-- > valid (mapKeysMonotonic (\ _ -> 1) (fromList ((5,"a") :| [(3,"b")]))) == False+mapKeysMonotonic ::+ (Key -> Key) ->+ NEIntMap a ->+ NEIntMap a+mapKeysMonotonic f (NEIntMap k v m) =+ NEIntMap (f k) v+ . M.mapKeysMonotonic f+ $ m+{-# INLINE mapKeysMonotonic #-}++-- | /O(n)/. Fold the keys and values in the map using the given right-associative+-- binary operator, such that+-- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.+--+-- For example,+--+-- > keysList map = foldrWithKey (\k x ks -> k:ks) [] map+foldrWithKey :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b+foldrWithKey f z (NEIntMap k v m) = f k v . M.foldrWithKey f z $ m+{-# INLINE foldrWithKey #-}++-- | /O(n)/. Fold the keys and values in the map using the given left-associative+-- binary operator, such that+-- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.+--+-- For example,+--+-- > keysList = reverse . foldlWithKey (\ks k x -> k:ks) []+foldlWithKey :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a+foldlWithKey f z (NEIntMap k v m) = M.foldlWithKey f (f z k v) m+{-# INLINE foldlWithKey #-}++-- | /O(n)/. A strict version of 'foldr1'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldr1' :: (a -> a -> a) -> NEIntMap a -> a+foldr1' f (NEIntMap _ v m) = case M.maxView m of+ Nothing -> v+ Just (y, m') -> let !z = M.foldr' f y m' in v `f` z+{-# INLINE foldr1' #-}++-- | /O(n)/. A strict version of 'foldl1'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldl1' :: (a -> a -> a) -> NEIntMap a -> a+foldl1' f (NEIntMap _ v m) = M.foldl' f v m+{-# INLINE foldl1' #-}++-- | /O(n)/. A strict version of 'foldrWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldrWithKey' :: (Key -> a -> b -> b) -> b -> NEIntMap a -> b+foldrWithKey' f z (NEIntMap k v m) = f k v y+ where+ !y = M.foldrWithKey f z m+{-# INLINE foldrWithKey' #-}++-- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldlWithKey' :: (a -> Key -> b -> a) -> a -> NEIntMap b -> a+foldlWithKey' f z (NEIntMap k v m) = M.foldlWithKey' f x m+ where+ !x = f z k v+{-# INLINE foldlWithKey' #-}++-- | /O(n)/. Return all keys of the map in ascending order.+--+-- > keys (fromList ((5,"a") :| [(3,"b")])) == (3 :| [5])+keys :: NEIntMap a -> NonEmpty Key+keys (NEIntMap k _ m) = k :| M.keys m+{-# INLINE keys #-}++-- | /O(n)/. An alias for 'toAscList'. Return all key\/value pairs in the map+-- in ascending key order.+--+-- > assocs (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+assocs :: NEIntMap a -> NonEmpty (Key, a)+assocs = toList+{-# INLINE assocs #-}++-- | /O(n)/. The non-empty set of all keys of the map.+--+-- > keysSet (fromList ((5,"a") :| [(3,"b")])) == Data.Set.NonEmpty.fromList (3 :| [5])+keysSet :: NEIntMap a -> NEIntSet+keysSet (NEIntMap k _ m) = NEIntSet k (M.keysSet m)+{-# INLINE keysSet #-}++-- | /O(n)/. Convert the map to a list of key\/value pairs where the keys are+-- in ascending order.+--+-- > toAscList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+toAscList :: NEIntMap a -> NonEmpty (Key, a)+toAscList = toList+{-# INLINE toAscList #-}++-- | /O(n)/. Convert the map to a list of key\/value pairs where the keys+-- are in descending order.+--+-- > toDescList (fromList ((5,"a") :| [(3,"b")])) == ((5,"a") :| [(3,"b")])+toDescList :: NEIntMap a -> NonEmpty (Key, a)+toDescList (NEIntMap k0 v0 m) = M.foldlWithKey' go ((k0, v0) :| []) m+ where+ go xs k v = (k, v) NE.<| xs+{-# INLINE toDescList #-}++-- | /O(n)/. Filter all values that satisfy the predicate.+--+-- Returns a potentially empty map ('IntMap'), because we could+-- potentailly filter out all items in the original 'NEIntMap'.+--+-- > filter (> "a") (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"+-- > filter (> "x") (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.empty+-- > filter (< "a") (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.empty+filter ::+ (a -> Bool) ->+ NEIntMap a ->+ IntMap a+filter f (NEIntMap k v m)+ | f v = insertMinMap k v . M.filter f $ m+ | otherwise = M.filter f m+{-# INLINE filter #-}++-- | /O(n)/. Filter all keys\/values that satisfy the predicate.+--+-- Returns a potentially empty map ('IntMap'), because we could+-- potentailly filter out all items in the original 'NEIntMap'.+--+-- > filterWithKey (\k _ -> k > 4) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+filterWithKey ::+ (Key -> a -> Bool) ->+ NEIntMap a ->+ IntMap a+filterWithKey f (NEIntMap k v m)+ | f k v = insertMinMap k v . M.filterWithKey f $ m+ | otherwise = M.filterWithKey f m+{-# INLINE filterWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Restrict an 'NEIntMap' to only those keys+-- found in a 'Data.Set.Set'.+--+-- @+-- m \`restrictKeys\` s = 'filterWithKey' (\k _ -> k ``Set.member`` s) m+-- m \`restrictKeys\` s = m ``intersection`` 'fromSet' (const ()) s+-- @+restrictKeys ::+ NEIntMap a ->+ IntSet ->+ IntMap a+restrictKeys n@(NEIntMap k v m) xs = case S.minView xs of+ Nothing -> M.empty+ Just (y, ys) -> case compare k y of+ -- k is not in xs+ LT -> m `M.restrictKeys` xs+ -- k and y are a part of the result+ EQ -> insertMinMap k v $ m `M.restrictKeys` ys+ -- y is not in m+ GT -> toMap n `M.restrictKeys` ys+{-# INLINE restrictKeys #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Remove all keys in a 'Data.Set.Set' from+-- an 'NEIntMap'.+--+-- @+-- m \`withoutKeys\` s = 'filterWithKey' (\k _ -> k ``Set.notMember`` s) m+-- m \`withoutKeys\` s = m ``difference`` 'fromSet' (const ()) s+-- @+withoutKeys ::+ NEIntMap a ->+ IntSet ->+ IntMap a+withoutKeys n@(NEIntMap k v m) xs = case S.minView xs of+ Nothing -> toMap n+ Just (y, ys) -> case compare k y of+ -- k is not in xs, so cannot be deleted+ LT -> insertMinMap k v $ m `M.withoutKeys` xs+ -- y deletes k, and only k+ EQ -> m `M.withoutKeys` ys+ -- y is not in n, so cannot delete anything, so we can just difference n and ys+ GT -> toMap n `M.withoutKeys` ys+{-# INLINE withoutKeys #-}++-- | /O(n)/. Partition the map according to a predicate.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate was true for all items.+-- * @'That' n2@ means that the predicate was false for all items.+-- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the+-- predicate) and @n2@ (all of the items that were false for the+-- predicate).+--+-- See also 'split'.+--+-- > partition (> "a") (fromList ((5,"a") :| [(3,"b")])) == These (singleton 3 "b") (singleton 5 "a")+-- > partition (< "x") (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))+-- > partition (> "x") (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))+partition ::+ (a -> Bool) ->+ NEIntMap a ->+ These (NEIntMap a) (NEIntMap a)+partition f = partitionWithKey (const f)+{-# INLINE partition #-}++-- | /O(n)/. Partition the map according to a predicate.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate was true for all items,+-- returning the original map.+-- * @'That' n2@ means that the predicate was false for all items,+-- returning the original map.+-- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the+-- predicate) and @n2@ (all of the items that were false for the+-- predicate).+--+-- See also 'split'.+--+-- > partitionWithKey (\ k _ -> k > 3) (fromList ((5,"a") :| [(3,"b")])) == These (singleton 5 "a") (singleton 3 "b")+-- > partitionWithKey (\ k _ -> k < 7) (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))+-- > partitionWithKey (\ k _ -> k > 7) (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))+partitionWithKey ::+ (Key -> a -> Bool) ->+ NEIntMap a ->+ These (NEIntMap a) (NEIntMap a)+partitionWithKey f n@(NEIntMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing)+ | f k v -> This n+ | otherwise -> That n+ (Just n1, Nothing)+ | f k v -> This n+ | otherwise -> These n1 (singleton k v)+ (Nothing, Just n2)+ | f k v -> These (singleton k v) n2+ | otherwise -> That n+ (Just n1, Just n2)+ | f k v -> These (insertMapMin k v m1) n2+ | otherwise -> These n1 (insertMapMin k v m2)+ where+ (m1, m2) = M.partitionWithKey f m0+{-# INLINEABLE partitionWithKey #-}++-- | /O(n)/. Map values and collect the 'Just' results.+--+-- Returns a potentially empty map ('IntMap'), because the function could+-- potentially return 'Nothing' on all items in the 'NEIntMap'.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > mapMaybe f (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "new a"+mapMaybe ::+ (a -> Maybe b) ->+ NEIntMap a ->+ IntMap b+mapMaybe f = mapMaybeWithKey (const f)+{-# INLINE mapMaybe #-}++-- | /O(n)/. Map keys\/values and collect the 'Just' results.+--+-- Returns a potentially empty map ('IntMap'), because the function could+-- potentially return 'Nothing' on all items in the 'NEIntMap'.+--+-- > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing+-- > mapMaybeWithKey f (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "key : 3"+mapMaybeWithKey ::+ (Key -> a -> Maybe b) ->+ NEIntMap a ->+ IntMap b+mapMaybeWithKey f (NEIntMap k v m) = maybe id (insertMinMap k) (f k v) (M.mapMaybeWithKey f m)+{-# INLINE mapMaybeWithKey #-}++-- | /O(n)/. Map values and separate the 'Left' and 'Right' results.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the results were all 'Left'.+-- * @'That' n2@ means that the results were all 'Right'.+-- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')+-- and @n2@ (the map where the results were 'Right')+--+-- > let f a = if a < "c" then Left a else Right a+-- > mapEither f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == These (fromList ((3,"b") :| [(5,"a")])) (fromList ((1,"x") :| [(7,"z")]))+-- >+-- > mapEither (\ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == That (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+mapEither ::+ (a -> Either b c) ->+ NEIntMap a ->+ These (NEIntMap b) (NEIntMap c)+mapEither f = mapEitherWithKey (const f)+{-# INLINE mapEither #-}++-- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the results were all 'Left'.+-- * @'That' n2@ means that the results were all 'Right'.+-- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')+-- and @n2@ (the map where the results were 'Right')+--+-- > let f k a = if k < 5 then Left (k * 2) else Right (a ++ a)+-- > mapEitherWithKey f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == These (fromList ((1,2) :| [(3,6)])) (fromList ((5,"aa") :| [(7,"zz")]))+-- >+-- > mapEitherWithKey (\_ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == That (fromList ((1,"x") :| [(3,"b"), (5,"a"), (7,"z")]))+mapEitherWithKey ::+ (Key -> a -> Either b c) ->+ NEIntMap a ->+ These (NEIntMap b) (NEIntMap c)+mapEitherWithKey f (NEIntMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> case f k v of+ Left v' -> This (singleton k v')+ Right v' -> That (singleton k v')+ (Just n1, Nothing) -> case f k v of+ Left v' -> This (insertMapMin k v' m1)+ Right v' -> These n1 (singleton k v')+ (Nothing, Just n2) -> case f k v of+ Left v' -> These (singleton k v') n2+ Right v' -> That (insertMapMin k v' m2)+ (Just n1, Just n2) -> case f k v of+ Left v' -> These (insertMapMin k v' m1) n2+ Right v' -> These n1 (insertMapMin k v' m2)+ where+ (m1, m2) = M.mapEitherWithKey f m0+{-# INLINEABLE mapEitherWithKey #-}++-- | /O(log n)/. The expression (@'split' k map@) is potentially a 'These'+-- containing up to two 'NEIntMap's based on splitting the map into maps+-- containing items before and after the given key @k@. It will never+-- return a map that contains @k@ itself.+--+-- * 'Nothing' means that @k@ was the only key in the the original map,+-- and so there are no items before or after it.+-- * @'Just' ('This' n1)@ means @k@ was larger than or equal to all items+-- in the map, and @n1@ is the entire original map (minus @k@, if it was+-- present)+-- * @'Just' ('That' n2)@ means @k@ was smaller than or equal to all+-- items in the map, and @n2@ is the entire original map (minus @k@, if+-- it was present)+-- * @'Just' ('These' n1 n2)@ gives @n1@ (the map of all keys from the+-- original map less than @k@) and @n2@ (the map of all keys from the+-- original map greater than @k@)+--+-- > split 2 (fromList ((5,"a") :| [(3,"b")])) == Just (That (fromList ((3,"b") :| [(5,"a")])) )+-- > split 3 (fromList ((5,"a") :| [(3,"b")])) == Just (That (singleton 5 "a") )+-- > split 4 (fromList ((5,"a") :| [(3,"b")])) == Just (These (singleton 3 "b") (singleton 5 "a"))+-- > split 5 (fromList ((5,"a") :| [(3,"b")])) == Just (This (singleton 3 "b") )+-- > split 6 (fromList ((5,"a") :| [(3,"b")])) == Just (This (fromList ((3,"b") :| [(5,"a")])) )+-- > split 5 (singleton 5 "a") == Nothing+split ::+ Key ->+ NEIntMap a ->+ Maybe (These (NEIntMap a) (NEIntMap a))+split k n@(NEIntMap k0 v m0) = case compare k k0 of+ LT -> Just $ That n+ EQ -> That <$> nonEmptyMap m0+ GT -> Just $ case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k0 v)+ (Just _, Nothing) -> This (insertMapMin k0 v m1)+ (Nothing, Just n2) -> These (singleton k0 v) n2+ (Just _, Just n2) -> These (insertMapMin k0 v m1) n2+ where+ (m1, m2) = M.split k m0+{-# INLINEABLE split #-}++-- | /O(log n)/. The expression (@'splitLookup' k map@) splits a map just+-- like 'split' but also returns @'lookup' k map@, as the first field in+-- the 'These':+--+-- > splitLookup 2 (fromList ((5,"a") :| [(3,"b")])) == That (That (fromList ((3,"b") :| [(5,"a")])))+-- > splitLookup 3 (fromList ((5,"a") :| [(3,"b")])) == These "b" (That (singleton 5 "a"))+-- > splitLookup 4 (fromList ((5,"a") :| [(3,"b")])) == That (These (singleton 3 "b") (singleton 5 "a"))+-- > splitLookup 5 (fromList ((5,"a") :| [(3,"b")])) == These "a" (This (singleton 3 "b"))+-- > splitLookup 6 (fromList ((5,"a") :| [(3,"b")])) == That (This (fromList ((3,"b") :| [(5,"a")])))+-- > splitLookup 5 (singleton 5 "a") == This "a"+splitLookup ::+ Key ->+ NEIntMap a ->+ These a (These (NEIntMap a) (NEIntMap a))+splitLookup k n@(NEIntMap k0 v0 m0) = case compare k k0 of+ LT -> That . That $ n+ EQ -> maybe (This v0) (These v0 . That) . nonEmptyMap $ m0+ GT -> maybe That These v $ case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k0 v0)+ (Just _, Nothing) -> This (insertMapMin k0 v0 m1)+ (Nothing, Just n2) -> These (singleton k0 v0) n2+ (Just _, Just n2) -> These (insertMapMin k0 v0 m1) n2+ where+ (m1, v, m2) = M.splitLookup k m0+{-# INLINEABLE splitLookup #-}++-- | /O(1)/. Decompose a map into pieces based on the structure of the+-- underlying tree. This function is useful for consuming a map in+-- parallel.+--+-- No guarantee is made as to the sizes of the pieces; an internal, but+-- deterministic process determines this. However, it is guaranteed that+-- the pieces returned will be in ascending order (all elements in the+-- first submap less than all elements in the second, and so on).+--+-- Note that the current implementation does not return more than four+-- submaps, but you should not depend on this behaviour because it can+-- change in the future without notice.+splitRoot ::+ NEIntMap a ->+ NonEmpty (NEIntMap a)+splitRoot (NEIntMap k v m) =+ singleton k v+ :| Maybe.mapMaybe nonEmptyMap (M.splitRoot m)+{-# INLINE splitRoot #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).+isSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool+isSubmapOf = isSubmapOfBy (==)+{-# INLINE isSubmapOf #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if+-- all keys in @t1@ are in tree @t2@, and when @f@ returns 'True' when+-- applied to their respective values. For example, the following+-- expressions are all 'True':+--+-- > isSubmapOfBy (==) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (<=) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (fromList (('a',1) :| [('b',2)]))+--+-- But the following are all 'False':+--+-- > isSubmapOfBy (==) (singleton 'a' 2) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (<) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (singleton 'a' 1)+isSubmapOfBy ::+ (a -> b -> Bool) ->+ NEIntMap a ->+ NEIntMap b ->+ Bool+isSubmapOfBy f (NEIntMap k v m0) (toMap -> m1) =+ kvSub+ && M.isSubmapOfBy f m0 m1+ where+ kvSub = case M.lookup k m1 of+ Just v0 -> f v v0+ Nothing -> False+{-# INLINE isSubmapOfBy #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Is this a proper submap? (ie. a submap+-- but not equal). Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy'+-- (==)@).+isProperSubmapOf :: Eq a => NEIntMap a -> NEIntMap a -> Bool+isProperSubmapOf = isProperSubmapOfBy (==)+{-# INLINE isProperSubmapOf #-}++-- | /O(m*log(n\/m + 1)), m <= n/. 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 values. For+-- example, the following expressions are all 'True':+--+-- > isProperSubmapOfBy (==) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+-- > isProperSubmapOfBy (<=) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+--+-- But the following are all 'False':+--+-- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (fromList ((1,1) :| [(2,2)]))+-- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (singleton 1 1))+-- > isProperSubmapOfBy (<) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+isProperSubmapOfBy ::+ (a -> b -> Bool) ->+ NEIntMap a ->+ NEIntMap b ->+ Bool+isProperSubmapOfBy f m1 m2 =+ M.size (neimIntMap m1) < M.size (neimIntMap m2)+ && isSubmapOfBy f m1 m2+{-# INLINE isProperSubmapOfBy #-}++-- | /O(1)/. The minimal key of the map. Note that this is total, making+-- 'Data.IntMap.lookupMin' obsolete. It is constant-time, so has better+-- asymptotics than @Data.IntMap.lookupMin@ and @Data.IntMap.findMin@, as well.+--+-- > findMin (fromList ((5,"a") :| [(3,"b")])) == (3,"b")+findMin :: NEIntMap a -> (Key, a)+findMin (NEIntMap k v _) = (k, v)+{-# INLINE findMin #-}++-- | /O(log n)/. The maximal key of the map. Note that this is total, making+-- 'Data.IntMap.lookupMin' obsolete.+--+-- > findMax (fromList ((5,"a") :| [(3,"b")])) == (5,"a")+findMax :: NEIntMap a -> (Key, a)+findMax (NEIntMap k v m) = fromMaybe (k, v) . M.lookupMax $ m+{-# INLINE findMax #-}++-- | /O(1)/. Delete the minimal key. Returns a potentially empty map+-- ('IntMap'), because we might end up deleting the final key in a singleton+-- map. It is constant-time, so has better asymptotics than+-- 'Data.IntMap.deleteMin'.+--+-- > deleteMin (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.IntMap.fromList [(5,"a"), (7,"c")]+-- > deleteMin (singleton 5 "a") == Data.IntMap.empty+deleteMin :: NEIntMap a -> IntMap a+deleteMin (NEIntMap _ _ m) = m+{-# INLINE deleteMin #-}++-- | /O(log n)/. Delete the maximal key. Returns a potentially empty map+-- ('IntMap'), because we might end up deleting the final key in a singleton+-- map.+--+-- > deleteMax (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.IntMap.fromList [(3,"b"), (5,"a")]+-- > deleteMax (singleton 5 "a") == Data.IntMap.empty+deleteMax :: NEIntMap a -> IntMap a+deleteMax (NEIntMap k v m) = case M.maxView m of+ Nothing -> M.empty+ Just (_, m') -> insertMinMap k v m'+{-# INLINE deleteMax #-}++-- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the+-- minimal key. Returns a potentially empty map ('IntMap'), because we might+-- end up deleting the final key in the map if the function returns+-- 'Nothing'. See 'adjustMin' for a version that can guaruntee that we+-- return a non-empty map.+--+-- > updateMin (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "Xb"), (5, "a")]+-- > updateMin (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+updateMin :: (a -> Maybe a) -> NEIntMap a -> IntMap a+updateMin f = updateMinWithKey (const f)+{-# INLINE updateMin #-}++-- | /O(1)/. A version of 'updateMin' that disallows deletion, allowing us+-- to guarantee that the result is also non-empty.+adjustMin :: (a -> a) -> NEIntMap a -> NEIntMap a+adjustMin f = adjustMinWithKey (const f)+{-# INLINE adjustMin #-}++-- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the+-- minimal key. Returns a potentially empty map ('IntMap'), because we might+-- end up deleting the final key in the map if the function returns+-- 'Nothing'. See 'adjustMinWithKey' for a version that guaruntees+-- a non-empty map.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+updateMinWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a+updateMinWithKey f (NEIntMap k v m) = maybe id (insertMinMap k) (f k v) m+{-# INLINE updateMinWithKey #-}++-- | /O(1)/. A version of 'adjustMaxWithKey' that disallows deletion,+-- allowing us to guarantee that the result is also non-empty. Note that+-- it also is able to have better asymptotics than 'updateMinWithKey' in+-- general.+adjustMinWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a+adjustMinWithKey f (NEIntMap k v m) = NEIntMap k (f k v) m+{-# INLINE adjustMinWithKey #-}++-- | /O(log n)/. Update the value at the maximal key. Returns+-- a potentially empty map ('IntMap'), because we might end up deleting the+-- final key in the map if the function returns 'Nothing'. See 'adjustMax'+-- for a version that can guarantee that we return a non-empty map.+--+-- > updateMax (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3, "b"), (5, "Xa")]+-- > updateMax (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 3 "b"+updateMax :: (a -> Maybe a) -> NEIntMap a -> IntMap a+updateMax f = updateMaxWithKey (const f)+{-# INLINE updateMax #-}++-- | /O(log n)/. A version of 'updateMax' that disallows deletion, allowing+-- us to guarantee that the result is also non-empty.+adjustMax :: (a -> a) -> NEIntMap a -> NEIntMap a+adjustMax f = adjustMaxWithKey (const f)+{-# INLINE adjustMax #-}++-- | /O(log n)/. Update the value at the maximal key. Returns+-- a potentially empty map ('IntMap'), because we might end up deleting the+-- final key in the map if the function returns 'Nothing'. See+-- 'adjustMaxWithKey' for a version that guaruntees a non-empty map.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.IntMap.singleton 5 "a"+updateMaxWithKey :: (Key -> a -> Maybe a) -> NEIntMap a -> IntMap a+updateMaxWithKey f (NEIntMap k v m)+ | M.null m = maybe m (M.singleton k) $ f k v+ | otherwise =+ insertMinMap k v+ . M.updateMaxWithKey f+ $ m+{-# INLINE updateMaxWithKey #-}++-- | /O(log n)/. A version of 'updateMaxWithKey' that disallows deletion,+-- allowing us to guarantee that the result is also non-empty.+adjustMaxWithKey :: (Key -> a -> a) -> NEIntMap a -> NEIntMap a+adjustMaxWithKey f (NEIntMap k0 v m)+ | M.null m = NEIntMap k0 (f k0 v) m+ | otherwise =+ insertMapMin k0 v+ . M.updateMaxWithKey (\k -> Just . f k)+ $ m+{-# INLINE adjustMaxWithKey #-}++-- | /O(1)/. Retrieves the value associated with minimal key of the+-- map, and the map stripped of that element. It is constant-time, so has+-- better asymptotics than @Data.IntMap.minView@ for 'IntMap'.+--+-- Note that unlike @Data.IntMap.minView@ for 'IntMap', this cannot ever fail,+-- so doesn't need to return in a 'Maybe'. However, the result 'IntMap' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > minView (fromList ((5,"a") :| [(3,"b")])) == ("b", Data.IntMap.singleton 5 "a")+minView :: NEIntMap a -> (a, IntMap a)+minView = first snd . deleteFindMin+{-# INLINE minView #-}++-- | /O(1)/. Delete and find the minimal key-value pair. It is+-- constant-time, so has better asymptotics that @Data.IntMap.minView@ for+-- 'IntMap'.+--+-- Note that unlike @Data.IntMap.deleteFindMin@ for 'IntMap', this cannot ever+-- fail, and so is a total function. However, the result 'IntMap' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > deleteFindMin (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((3,"b"), Data.IntMap.fromList [(5,"a"), (10,"c")])+deleteFindMin :: NEIntMap a -> ((Key, a), IntMap a)+deleteFindMin (NEIntMap k v m) = ((k, v), m)+{-# INLINE deleteFindMin #-}++-- | /O(log n)/. Retrieves the value associated with maximal key of the+-- map, and the map stripped of that element.+--+-- Note that unlike @Data.IntMap.maxView@ from 'IntMap', this cannot ever fail,+-- so doesn't need to return in a 'Maybe'. However, the result 'IntMap' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > maxView (fromList ((5,"a") :| [(3,"b")])) == ("a", Data.IntMap.singleton 3 "b")+maxView :: NEIntMap a -> (a, IntMap a)+maxView = first snd . deleteFindMax+{-# INLINE maxView #-}++-- | /O(log n)/. Delete and find the minimal key-value pair.+--+-- Note that unlike @Data.IntMap.deleteFindMax@ for 'IntMap', this cannot ever+-- fail, and so is a total function. However, the result 'IntMap' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > deleteFindMax (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((10,"c"), Data.IntMap.fromList [(3,"b"), (5,"a")])+deleteFindMax :: NEIntMap a -> ((Key, a), IntMap a)+deleteFindMax (NEIntMap k v m) =+ maybe ((k, v), M.empty) (second (insertMinMap k v))+ . M.maxViewWithKey+ $ m+{-# INLINE deleteFindMax #-}++-- ---------------------------+-- Combining functions+-- ---------------------------+--+-- Code comes from "Data.Map.Internal" from containers, modified slightly+-- to work with NonEmpty+--+-- Copyright : (c) Daan Leijen 2002+-- (c) Andriy Palamarchuk 2008++combineEq :: NonEmpty (Key, b) -> NonEmpty (Key, b)+combineEq = \case+ x :| [] -> x :| []+ x :| xx@(_ : _) -> go x xx+ where+ go z [] = z :| []+ go z@(kz, _) (x@(kx, xx) : xs')+ | kx == kz = go (kx, xx) xs'+ | otherwise = z NE.<| go x xs'++combineEqWith ::+ (Key -> b -> b -> b) ->+ NonEmpty (Key, b) ->+ NonEmpty (Key, b)+combineEqWith f = \case+ x :| [] -> x :| []+ x :| xx@(_ : _) -> go x xx+ where+ go z [] = z :| []+ go z@(kz, zz) (x@(kx, xx) : xs')+ | kx == kz = let yy = f kx xx zz in go (kx, yy) xs'+ | otherwise = z NE.<| go x xs'
+ src/Data/IntMap/NonEmpty/Strict/Internal.hs view
@@ -0,0 +1,186 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE PatternSynonyms #-}+{-# OPTIONS_HADDOCK not-home #-}++-- |+-- Module : Data.IntMap.NonEmpty.Strict.Internal+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- Strict internal-use functions used in the implementation of+-- "Data.IntMap.NonEmpty.Strict". These share the same 'NEIntMap' type as+-- the lazy modules; only construction is strict in the value.+module Data.IntMap.NonEmpty.Strict.Internal (+ -- * Non-Empty IntMap type+ NEIntMap,+ pattern NEIntMap,+ neimIntMap,+ Key,+ singleton,+ nonEmptyMap,+ withNonEmpty,+ fromList,+ toList,+ map,+ insertWith,+ union,+ unions,+ elems,+ size,+ toMap,++ -- * Folds+ foldr,+ foldr',+ foldr1,+ foldl,+ foldl',+ foldl1,++ -- * Traversals+ traverseWithKey,+ traverseWithKey1,+ foldMapWithKey,++ -- * Unsafe IntMap Functions+ insertMinMap,+ insertMaxMap,++ -- * Debug+ valid,+) where++import Control.Applicative+import qualified Data.Foldable as F+import Data.Functor.Apply (Apply, MaybeApply (..), (<.>))+import Data.IntMap.Internal (IntMap, Key)+import qualified Data.IntMap.NonEmpty.Lazy.Internal as L+import qualified Data.IntMap.Strict as M+import Data.List.NonEmpty (NonEmpty (..))+import Data.Semigroup.Foldable (Foldable1)+import qualified Data.Semigroup.Foldable as F1+import Prelude hiding (Foldable (..), foldl, foldl1, foldr, foldr1, map)++type NEIntMap = L.NEIntMap++pattern NEIntMap :: Key -> a -> IntMap a -> NEIntMap a+pattern NEIntMap k v m <- L.NEIntMap k v m+ where+ NEIntMap k !v m = L.NEIntMap k v m++{-# COMPLETE NEIntMap #-}++neimIntMap :: NEIntMap a -> IntMap a+neimIntMap (NEIntMap _ _ m) = m+{-# INLINE neimIntMap #-}++singleton :: Key -> a -> NEIntMap a+singleton k !v = L.NEIntMap k v M.empty+{-# INLINE singleton #-}++nonEmptyMap :: IntMap a -> Maybe (NEIntMap a)+nonEmptyMap = L.nonEmptyMap+{-# INLINE nonEmptyMap #-}++withNonEmpty :: b -> (NEIntMap a -> b) -> IntMap a -> b+withNonEmpty = L.withNonEmpty+{-# INLINE withNonEmpty #-}++fromList :: NonEmpty (Key, a) -> NEIntMap a+fromList ((k, v) :| xs) = F.foldl' (\m (k', v') -> insertWith const k' v' m) (singleton k v) xs+{-# INLINE fromList #-}++toList :: NEIntMap a -> NonEmpty (Key, a)+toList = L.toList+{-# INLINE toList #-}++map :: (a -> b) -> NEIntMap a -> NEIntMap b+map f (NEIntMap k v m) = NEIntMap k (f v) (M.map f m)+{-# INLINE map #-}++insertWith :: (a -> a -> a) -> Key -> a -> NEIntMap a -> NEIntMap a+insertWith f k !v n@(NEIntMap k0 v0 m) = case compare k k0 of+ LT -> NEIntMap k v (toMap n)+ EQ -> NEIntMap k0 (f v v0) m+ GT -> NEIntMap k0 v0 (M.insertWith f k v m)+{-# INLINE insertWith #-}++union :: NEIntMap a -> NEIntMap a -> NEIntMap a+union n1@(NEIntMap k1 v1 m1) n2@(NEIntMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEIntMap k1 v1 . M.union m1 . toMap $ n2+ EQ -> NEIntMap k1 v1 . M.union m1 $ m2+ GT -> NEIntMap k2 v2 . M.union (toMap n1) $ m2+{-# INLINE union #-}++unions :: Foldable1 f => f (NEIntMap a) -> NEIntMap a+unions ns = case F1.toNonEmpty ns of+ m :| ms -> F.foldl' union m ms+{-# INLINE unions #-}++elems :: NEIntMap a -> NonEmpty a+elems = fmap snd . toList+{-# INLINE elems #-}++size :: NEIntMap a -> Int+size = L.size+{-# INLINE size #-}++toMap :: NEIntMap a -> IntMap a+toMap (NEIntMap k v m) = insertMinMap k v m+{-# INLINE toMap #-}++foldr :: (a -> b -> b) -> b -> NEIntMap a -> b+foldr = L.foldr+{-# INLINE foldr #-}++foldr' :: (a -> b -> b) -> b -> NEIntMap a -> b+foldr' = L.foldr'+{-# INLINE foldr' #-}++foldr1 :: (a -> a -> a) -> NEIntMap a -> a+foldr1 = L.foldr1+{-# INLINE foldr1 #-}++foldl :: (b -> a -> b) -> b -> NEIntMap a -> b+foldl = L.foldl+{-# INLINE foldl #-}++foldl' :: (b -> a -> b) -> b -> NEIntMap a -> b+foldl' = L.foldl'+{-# INLINE foldl' #-}++foldl1 :: (a -> a -> a) -> NEIntMap a -> a+foldl1 = L.foldl1+{-# INLINE foldl1 #-}++traverseWithKey :: Applicative f => (Key -> a -> f b) -> NEIntMap a -> f (NEIntMap b)+traverseWithKey f (NEIntMap k v m) = NEIntMap k <$> f k v <*> M.traverseWithKey f m+{-# INLINE traverseWithKey #-}++traverseWithKey1 :: Apply f => (Key -> a -> f b) -> NEIntMap a -> f (NEIntMap b)+traverseWithKey1 f (NEIntMap k0 v m0) = case runMaybeApply m1 of+ Left m2 -> NEIntMap k0 <$> f k0 v <.> m2+ Right m2 -> flip (NEIntMap k0) m2 <$> f k0 v+ where+ m1 = M.traverseWithKey (\k -> MaybeApply . Left . f k) m0+{-# INLINE traverseWithKey1 #-}++foldMapWithKey :: Monoid m => (Key -> a -> m) -> NEIntMap a -> m+foldMapWithKey = L.foldMapWithKey+{-# INLINE foldMapWithKey #-}++valid :: NEIntMap a -> Bool+valid (NEIntMap k _ m) =+ all ((k <) . fst . fst) (M.minViewWithKey m)++insertMinMap :: Key -> a -> IntMap a -> IntMap a+insertMinMap k !v = M.insert k v+{-# INLINE insertMinMap #-}++insertMaxMap :: Key -> a -> IntMap a -> IntMap a+insertMaxMap k !v = M.insert k v+{-# INLINE insertMaxMap #-}
src/Data/Map/NonEmpty.hs view
@@ -1,2495 +1,18 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE EmptyCase #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE ViewPatterns #-}---- |--- Module : Data.Map.NonEmpty--- Copyright : (c) Justin Le 2018--- License : BSD3------ Maintainer : justin@jle.im--- Stability : experimental--- Portability : non-portable------ = Non-Empty Finite Maps (lazy interface)------ The @'NEMap' k v@ type represents a non-empty finite map (sometimes--- called a dictionary) from keys of type @k@ to values of type @v@.--- An 'NEMap' is strict in its keys but lazy in its values.------ See documentation for 'NEMap' for information on how to convert and--- manipulate such non-empty maps.------ This module essentially re-imports the API of "Data.Map.Lazy" and its--- 'Map' type, along with semantics and asymptotics. In most situations,--- asymptotics are different only by a constant factor. In some--- situations, asmyptotics are even better (constant-time instead of--- log-time). All typeclass constraints are identical to their "Data.Map"--- counterparts.------ Because 'NEMap' is implemented using 'Map', all of the caveats of using--- 'Map' apply (such as the limitation of the maximum size of maps).------ All functions take non-empty maps as inputs. In situations where their--- results can be guarunteed to also be non-empty, they also return--- non-empty maps. In situations where their results could potentially be--- empty, 'Map' is returned instead.------ Some variants of functions (like 'alter'', 'alterF'', 'adjustAt',--- 'adjustMin', 'adjustMax', 'adjustMinWithKey', 'adjustMaxWithKey') are--- provided in a way restructured to preserve guaruntees of non-empty maps--- being returned.------ Some functions (like 'mapEither', 'partition', 'spanAntitone', 'split')--- have modified return types to account for possible configurations of--- non-emptiness.------ This module is intended to be imported qualified, to avoid name clashes with--- "Prelude" and "Data.Map" functions:------ > import qualified Data.Map.NonEmpty as NEM------ At the moment, this package does not provide a variant strict on values--- for these functions, like /containers/ does. This is a planned future--- implementation (PR's are appreciated). For now, you can simulate--- a strict interface by manually forcing values before returning results.-module Data.Map.NonEmpty (- -- * Non-Empty Map type- NEMap,-- -- ** Conversions between empty and non-empty maps- pattern IsNonEmpty,- pattern IsEmpty,- nonEmptyMap,- toMap,- withNonEmpty,- insertMap,- insertMapWith,- insertMapWithKey,- insertMapMin,- insertMapMax,- unsafeFromMap,-- -- * Construction- singleton,- fromSet,-- -- ** From Unordered Lists- fromList,- fromListWith,- fromListWithKey,-- -- ** From Ascending Lists- fromAscList,- fromAscListWith,- fromAscListWithKey,- fromDistinctAscList,-- -- ** From Descending Lists- fromDescList,- fromDescListWith,- fromDescListWithKey,- fromDistinctDescList,-- -- * Insertion- insert,- insertWith,- insertWithKey,- insertLookupWithKey,-- -- * Deletion\/Update- delete,- deleteMaybe,- adjust,- adjustWithKey,- update,- updateWithKey,- updateLookupWithKey,- alter,- alterF,- alter',- alterF',-- -- * Query-- -- ** Lookup- lookup,- (!?),- (!),- findWithDefault,- member,- notMember,- lookupLT,- lookupGT,- lookupLE,- lookupGE,- absurdNEMap,-- -- ** Size- size,-- -- * Combine-- -- ** Union- union,- unionMapLeft,- unionMapRight,- unionWith,- unionMapWithLeft,- unionMapWithRight,- unionWithKey,- unionMapWithKeyLeft,- unionMapWithKeyRight,- unions,- unionsWith,-- -- ** Difference- difference,- (\\),- differenceWith,- differenceWithKey,-- -- ** Intersection- intersection,- intersectionWith,- intersectionWithKey,- -- -- ** Unsafe general combining function- -- , mergeWithKey-- -- * Traversal-- -- ** Map- map,- mapWithKey,- traverseWithKey1,- traverseWithKey,- traverseMaybeWithKey1,- traverseMaybeWithKey,- mapAccum,- mapAccumWithKey,- mapAccumRWithKey,- mapKeys,- mapKeysWith,- mapKeysMonotonic,-- -- * Folds- foldr,- foldl,- foldr1,- foldl1,- foldrWithKey,- foldlWithKey,- foldMapWithKey,-- -- ** Strict folds- foldr',- foldr1',- foldl',- foldl1',- foldrWithKey',- foldlWithKey',-- -- * Conversion- elems,- keys,- assocs,- keysSet,-- -- ** Lists- toList,-- -- ** Ordered lists- toAscList,- toDescList,-- -- * Filter- filter,- filterWithKey,- restrictKeys,- withoutKeys,- partition,- partitionWithKey,- takeWhileAntitone,- dropWhileAntitone,- spanAntitone,- mapMaybe,- mapMaybeWithKey,- mapEither,- mapEitherWithKey,- split,- splitLookup,- splitRoot,-- -- * Submap- isSubmapOf,- isSubmapOfBy,- isProperSubmapOf,- isProperSubmapOfBy,-- -- * Indexed- lookupIndex,- findIndex,- elemAt,- updateAt,- adjustAt,- deleteAt,- take,- drop,- splitAt,-- -- * Min\/Max- findMin,- findMax,- deleteMin,- deleteMax,- deleteFindMin,- deleteFindMax,- updateMin,- updateMax,- adjustMin,- adjustMax,- updateMinWithKey,- updateMaxWithKey,- adjustMinWithKey,- adjustMaxWithKey,- minView,- maxView,-- -- * Debugging- valid,-) where--import Control.Applicative-import Data.Bifunctor-import qualified Data.Foldable as F-import Data.Function-import Data.Functor.Apply-import Data.Functor.Identity-import Data.List.NonEmpty (NonEmpty (..))-import qualified Data.List.NonEmpty as NE-import Data.Map (Map)-import qualified Data.Map as M-import Data.Map.NonEmpty.Internal-import Data.Maybe hiding (mapMaybe)-import qualified Data.Maybe as Maybe-import Data.Semigroup.Foldable (Foldable1)-import qualified Data.Semigroup.Foldable as F1-import Data.Set (Set)-import qualified Data.Set as S-import Data.Set.NonEmpty.Internal (NESet (..))-import Data.These-import Data.Void-import Prelude hiding (Foldable (..), drop, filter, lookup, map, splitAt, take)---- | /O(1)/ match, /O(log n)/ usage of contents. The 'IsNonEmpty' and--- 'IsEmpty' patterns allow you to treat a 'Map' as if it were either--- a @'IsNonEmpty' n@ (where @n@ is a 'NEMap') or an 'IsEmpty'.------ For example, you can pattern match on a 'Map':------ @--- myFunc :: 'Map' K X -> Y--- myFunc ('IsNonEmpty' n) = -- here, the user provided a non-empty map, and @n@ is the 'NEMap'--- myFunc 'IsEmpty' = -- here, the user provided an empty map.--- @------ Matching on @'IsNonEmpty' n@ means that the original 'Map' was /not/--- empty, and you have a verified-non-empty 'NEMap' @n@ to use.------ Note that patching on this pattern is /O(1)/. However, using the--- contents requires a /O(log n)/ cost that is deferred until after the--- pattern is matched on (and is not incurred at all if the contents are--- never used).------ A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides--- complete coverage.------ This is a bidirectional pattern, so you can use 'IsNonEmpty' to convert--- a 'NEMap' back into a 'Map', obscuring its non-emptiness (see 'toMap').-pattern IsNonEmpty :: NEMap k a -> Map k a-pattern IsNonEmpty n <- (nonEmptyMap -> Just n)- where- IsNonEmpty n = toMap n---- | /O(1)/. The 'IsNonEmpty' and 'IsEmpty' patterns allow you to treat--- a 'Map' as if it were either a @'IsNonEmpty' n@ (where @n@ is--- a 'NEMap') or an 'IsEmpty'.------ Matching on 'IsEmpty' means that the original 'Map' was empty.------ A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides--- complete coverage.------ This is a bidirectional pattern, so you can use 'IsEmpty' as an--- expression, and it will be interpreted as 'Data.Map.empty'.------ See 'IsNonEmpty' for more information.-pattern IsEmpty :: Map k a-pattern IsEmpty <- (M.null -> True)- where- IsEmpty = M.empty--{-# COMPLETE IsNonEmpty, IsEmpty #-}---- | /O(log n)/. Unsafe version of 'nonEmptyMap'. Coerces a 'Map' into an--- 'NEMap', but is undefined (throws a runtime exception when evaluation is--- attempted) for an empty 'Map'.-unsafeFromMap ::- Map k a ->- NEMap k a-unsafeFromMap = withNonEmpty e id- where- e = errorWithoutStackTrace "NEMap.unsafeFromMap: empty map"-{-# INLINE unsafeFromMap #-}---- | /O(n)/. Build a non-empty map from a non-empty set of keys and--- a function which for each key computes its value.------ > fromSet (\k -> replicate k 'a') (Data.Set.NonEmpty.fromList (3 :| [5])) == fromList ((5,"aaaaa") :| [(3,"aaa")])-fromSet ::- (k -> a) ->- NESet k ->- NEMap k a-fromSet f (NESet k ks) = NEMap k (f k) (M.fromSet f ks)-{-# INLINE fromSet #-}---- | /O(log n)/. Lookup the value at a key in the map.------ The function will return the corresponding value as @('Just' value)@,--- or 'Nothing' if the key isn't in the map.------ An example of using @lookup@:------ > import Prelude hiding (lookup)--- > import Data.Map.NonEmpty--- >--- > employeeDept = fromList (("John","Sales") :| [("Bob","IT")])--- > deptCountry = fromList (("IT","USA") :| [("Sales","France")])--- > countryCurrency = fromList (("USA", "Dollar") :| [("France", "Euro")])--- >--- > employeeCurrency :: String -> Maybe String--- > employeeCurrency name = do--- > dept <- lookup name employeeDept--- > country <- lookup dept deptCountry--- > lookup country countryCurrency--- >--- > main = do--- > putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))--- > putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))------ The output of this program:------ > John's currency: Just "Euro"--- > Pete's currency: Nothing-lookup ::- Ord k =>- k ->- NEMap k a ->- Maybe a-lookup k (NEMap k0 v m) = case compare k k0 of- LT -> Nothing- EQ -> Just v- GT -> M.lookup k m-{-# INLINE lookup #-}---- | /O(log n)/. Find the value at a key. Returns 'Nothing' when the--- element can not be found.------ prop> fromList ((5, 'a') :| [(3, 'b')]) !? 1 == Nothing--- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 5 == Just 'a'-(!?) :: Ord k => NEMap k a -> k -> Maybe a-(!?) = flip lookup-{-# INLINE (!?) #-}---- | /O(log n)/. Find the value at a key. Calls 'error' when the element--- can not be found.------ > fromList ((5,'a') :| [(3,'b')]) ! 1 Error: element not in the map--- > fromList ((5,'a') :| [(3,'b')]) ! 5 == 'a'-(!) :: Ord k => NEMap k a -> k -> a-(!) m k = fromMaybe e $ m !? k- where- e = error "NEMap.!: given key is not an element in the map"-{-# INLINE (!) #-}--infixl 9 !?-infixl 9 !---- | /O(log n)/. The expression @('findWithDefault' def k map)@ returns--- the value at key @k@ or returns default value @def@--- when the key is not in the map.------ > findWithDefault 'x' 1 (fromList ((5,'a') :| [(3,'b')])) == 'x'--- > findWithDefault 'x' 5 (fromList ((5,'a') :| [(3,'b')])) == 'a'-findWithDefault ::- Ord k =>- a ->- k ->- NEMap k a ->- a-findWithDefault def k (NEMap k0 v m) = case compare k k0 of- LT -> def- EQ -> v- GT -> M.findWithDefault def k m-{-# INLINE findWithDefault #-}---- | /O(log n)/. Is the key a member of the map? See also 'notMember'.------ > member 5 (fromList ((5,'a') :| [(3,'b')])) == True--- > member 1 (fromList ((5,'a') :| [(3,'b')])) == False-member :: Ord k => k -> NEMap k a -> Bool-member k (NEMap k0 _ m) = case compare k k0 of- LT -> False- EQ -> True- GT -> M.member k m-{-# INLINE member #-}---- | /O(log n)/. Is the key not a member of the map? See also 'member'.------ > notMember 5 (fromList ((5,'a') :| [(3,'b')])) == False--- > notMember 1 (fromList ((5,'a') :| [(3,'b')])) == True-notMember :: Ord k => k -> NEMap k a -> Bool-notMember k (NEMap k0 _ m) = case compare k k0 of- LT -> True- EQ -> False- GT -> M.notMember k m-{-# INLINE notMember #-}---- | /O(log n)/. Find largest key smaller than the given one and return the--- corresponding (key, value) pair.------ > lookupLT 3 (fromList ((3,'a') :| [(5,'b')])) == Nothing--- > lookupLT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')-lookupLT :: Ord k => k -> NEMap k a -> Maybe (k, a)-lookupLT k (NEMap k0 v m) = case compare k k0 of- LT -> Nothing- EQ -> Nothing- GT -> M.lookupLT k m <|> Just (k0, v)-{-# INLINE lookupLT #-}---- | /O(log n)/. Find smallest key greater than the given one and return the--- corresponding (key, value) pair.------ > lookupGT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')--- > lookupGT 5 (fromList ((3,'a') :| [(5,'b')])) == Nothing-lookupGT :: Ord k => k -> NEMap k a -> Maybe (k, a)-lookupGT k (NEMap k0 v m) = case compare k k0 of- LT -> Just (k0, v)- EQ -> M.lookupMin m- GT -> M.lookupGT k m-{-# INLINE lookupGT #-}---- | /O(log n)/. Find largest key smaller or equal to the given one and return--- the corresponding (key, value) pair.------ > lookupLE 2 (fromList ((3,'a') :| [(5,'b')])) == Nothing--- > lookupLE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')--- > lookupLE 5 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')-lookupLE :: Ord k => k -> NEMap k a -> Maybe (k, a)-lookupLE k (NEMap k0 v m) = case compare k k0 of- LT -> Nothing- EQ -> Just (k0, v)- GT -> M.lookupLE k m <|> Just (k0, v)-{-# INLINE lookupLE #-}---- | /O(log n)/. Find smallest key greater or equal to the given one and return--- the corresponding (key, value) pair.------ > lookupGE 3 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')--- > lookupGE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')--- > lookupGE 6 (fromList ((3,'a') :| [(5,'b')])) == Nothing-lookupGE :: Ord k => k -> NEMap k a -> Maybe (k, a)-lookupGE k (NEMap k0 v m) = case compare k k0 of- LT -> Just (k0, v)- EQ -> Just (k0, v)- GT -> M.lookupGE k m-{-# INLINE lookupGE #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union with a combining function.------ > unionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "aA"), (7, "C")])-unionWith ::- Ord k =>- (a -> a -> a) ->- NEMap k a ->- NEMap k a ->- NEMap k a-unionWith f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of- LT -> NEMap k1 v1 . M.unionWith f m1 . toMap $ n2- EQ -> NEMap k1 (f v1 v2) . M.unionWith f m1 $ m2- GT -> NEMap k2 v2 . M.unionWith f (toMap n1) $ m2-{-# INLINE unionWith #-}---- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a possibly-empty--- 'Map' and a non-empty map.------ @since 0.3.6.0-unionMapLeft :: Ord k => Map k a -> NEMap k a -> NEMap k a-unionMapLeft m n = withNonEmpty n (`union` n) m-{-# INLINE unionMapLeft #-}---- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a non-empty map and a--- possibly-empty 'Map'.------ @since 0.3.6.0-unionMapRight :: Ord k => NEMap k a -> Map k a -> NEMap k a-unionMapRight n = withNonEmpty n (union n)-{-# INLINE unionMapRight #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'Map' and a--- non-empty map with a combining function.------ @since 0.3.6.0-unionMapWithLeft :: Ord k => (a -> a -> a) -> Map k a -> NEMap k a -> NEMap k a-unionMapWithLeft f m n = withNonEmpty n (\m' -> unionWith f m' n) m-{-# INLINE unionMapWithLeft #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a--- possibly-empty 'Map' with a combining function.------ @since 0.3.6.0-unionMapWithRight :: Ord k => (a -> a -> a) -> NEMap k a -> Map k a -> NEMap k a-unionMapWithRight f n = withNonEmpty n (unionWith f n)-{-# INLINE unionMapWithRight #-}---- | /O(m*log(n\/m + 1)), m <= n/.--- Union with a combining function, given the matching key.------ > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value--- > unionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "5:a|A"), (7, "C")])-unionWithKey ::- Ord k =>- (k -> a -> a -> a) ->- NEMap k a ->- NEMap k a ->- NEMap k a-unionWithKey f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of- LT -> NEMap k1 v1 . M.unionWithKey f m1 . toMap $ n2- EQ -> NEMap k1 (f k1 v1 v2) . M.unionWithKey f m1 $ m2- GT -> NEMap k2 v2 . M.unionWithKey f (toMap n1) $ m2-{-# INLINE unionWithKey #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'Map' and a--- non-empty map with a combining function, given the matching key.------ @since 0.3.6.0-unionMapWithKeyLeft ::- Ord k =>- (k -> a -> a -> a) ->- Map k a ->- NEMap k a ->- NEMap k a-unionMapWithKeyLeft f m n = withNonEmpty n (\m' -> unionWithKey f m' n) m-{-# INLINE unionMapWithKeyLeft #-}---- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a--- possibly-empty 'Map' with a combining function, given the matching key.------ @since 0.3.6.0-unionMapWithKeyRight ::- Ord k =>- (k -> a -> a -> a) ->- NEMap k a ->- Map k a ->- NEMap k a-unionMapWithKeyRight f n = withNonEmpty n (unionWithKey f n)-{-# INLINE unionMapWithKeyRight #-}---- | The union of a non-empty list of maps, with a combining operation:--- (@'unionsWith' f == 'Data.Foldable.foldl1' ('unionWith' f)@).------ > unionsWith (++) (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])--- > == fromList ((3, "bB3") :| [(5, "aAA3"), (7, "C")])-unionsWith ::- (Foldable1 f, Ord k) =>- (a -> a -> a) ->- f (NEMap k a) ->- NEMap k a-unionsWith f (F1.toNonEmpty -> (m :| ms)) = F.foldl' (unionWith f) m ms-{-# INLINE unionsWith #-}---- | /O(m*log(n\/m + 1)), m <= n/. Difference of two maps.--- Return elements of the first map not existing in the second map.------ Returns a potentially empty map ('Map'), in case the first map is--- a subset of the second map.------ > difference (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 3 "b"-difference ::- Ord k =>- NEMap k a ->- NEMap k b ->- Map k a-difference n1@(NEMap k1 v1 m1) n2@(NEMap k2 _ m2) = case compare k1 k2 of- -- k1 is not in n2, so cannot be deleted- LT -> insertMinMap k1 v1 $ m1 `M.difference` toMap n2- -- k2 deletes k1, and only k1- EQ -> m1 `M.difference` m2- -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.- GT -> toMap n1 `M.difference` m2-{-# INLINE difference #-}---- | Same as 'difference'.-(\\) ::- Ord k =>- NEMap k a ->- NEMap k b ->- Map k a-(\\) = difference-{-# INLINE (\\) #-}---- | /O(n+m)/. Difference with a combining function.--- When two equal keys are--- encountered, the combining function is applied to the values of these keys.--- 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@.------ Returns a potentially empty map ('Map'), in case the first map is--- a subset of the second map and the function returns 'Nothing' for every--- pair.------ > let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing--- > differenceWith f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (7, "C")]))--- > == Data.Map.singleton 3 "b:B"-differenceWith ::- Ord k =>- (a -> b -> Maybe a) ->- NEMap k a ->- NEMap k b ->- Map k a-differenceWith f = differenceWithKey (const f)-{-# INLINE differenceWith #-}---- | /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@.------ Returns a potentially empty map ('Map'), in case the first map is--- a subset of the second map and the function returns 'Nothing' for every--- pair.------ > let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing--- > differenceWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (10, "C")]))--- > == Data.Map.singleton 3 "3:b|B"-differenceWithKey ::- Ord k =>- (k -> a -> b -> Maybe a) ->- NEMap k a ->- NEMap k b ->- Map k a-differenceWithKey f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of- -- k1 is not in n2, so cannot be deleted- LT -> insertMinMap k1 v1 $ M.differenceWithKey f m1 (toMap n2)- -- k2 deletes k1, and only k1- EQ -> maybe id (insertMinMap k1) (f k1 v1 v2) (M.differenceWithKey f m1 m2)- -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.- GT -> M.differenceWithKey f (toMap n1) m2-{-# INLINE differenceWithKey #-}---- | /O(m*log(n\/m + 1)), m <= n/. Intersection of two maps.--- Return data in the first map for the keys existing in both maps.--- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).------ Returns a potentially empty map ('Map'), in case the two maps share no--- keys in common.------ > intersection (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 5 "a"-intersection ::- Ord k =>- NEMap k a ->- NEMap k b ->- Map k a-intersection n1@(NEMap k1 v1 m1) n2@(NEMap k2 _ m2) = case compare k1 k2 of- -- k1 is not in n2- LT -> m1 `M.intersection` toMap n2- -- k1 and k2 are a part of the result- EQ -> insertMinMap k1 v1 $ m1 `M.intersection` m2- -- k2 is not in n1- GT -> toMap n1 `M.intersection` m2-{-# INLINE intersection #-}---- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.------ Returns a potentially empty map ('Map'), in case the two maps share no--- keys in common.------ > intersectionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 5 "aA"-intersectionWith ::- Ord k =>- (a -> b -> c) ->- NEMap k a ->- NEMap k b ->- Map k c-intersectionWith f = intersectionWithKey (const f)-{-# INLINE intersectionWith #-}---- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.------ Returns a potentially empty map ('Map'), in case the two maps share no--- keys in common.------ > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar--- > intersectionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 5 "5:a|A"-intersectionWithKey ::- Ord k =>- (k -> a -> b -> c) ->- NEMap k a ->- NEMap k b ->- Map k c-intersectionWithKey f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of- -- k1 is not in n2- LT -> M.intersectionWithKey f m1 (toMap n2)- -- k1 and k2 are a part of the result- EQ -> insertMinMap k1 (f k1 v1 v2) $ M.intersectionWithKey f m1 m2- -- k2 is not in n1- GT -> M.intersectionWithKey f (toMap n1) m2-{-# INLINE intersectionWithKey #-}---- | /O(n)/. A strict version of 'foldr1'. Each application of the operator--- is evaluated before using the result in the next application. This--- function is strict in the starting value.-foldr1' :: (a -> a -> a) -> NEMap k a -> a-foldr1' f (NEMap _ v m) = case M.maxView m of- Nothing -> v- Just (y, m') -> let !z = M.foldr' f y m' in v `f` z-{-# INLINE foldr1' #-}---- | /O(n)/. A strict version of 'foldl1'. Each application of the operator--- is evaluated before using the result in the next application. This--- function is strict in the starting value.-foldl1' :: (a -> a -> a) -> NEMap k a -> a-foldl1' f (NEMap _ v m) = M.foldl' f v m-{-# INLINE foldl1' #-}---- | /O(n)/. Fold the keys and values in the map using the given right-associative--- binary operator, such that--- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.------ For example,------ > keysList map = foldrWithKey (\k x ks -> k:ks) [] map-foldrWithKey :: (k -> a -> b -> b) -> b -> NEMap k a -> b-foldrWithKey f z (NEMap k v m) = f k v . M.foldrWithKey f z $ m-{-# INLINE foldrWithKey #-}---- | /O(n)/. A strict version of 'foldrWithKey'. Each application of the operator is--- evaluated before using the result in the next application. This--- function is strict in the starting value.-foldrWithKey' :: (k -> a -> b -> b) -> b -> NEMap k a -> b-foldrWithKey' f z (NEMap k v m) = f k v y- where- !y = M.foldrWithKey f z m-{-# INLINE foldrWithKey' #-}---- | /O(n)/. Fold the keys and values in the map using the given left-associative--- binary operator, such that--- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.------ For example,------ > keysList = reverse . foldlWithKey (\ks k x -> k:ks) []-foldlWithKey :: (a -> k -> b -> a) -> a -> NEMap k b -> a-foldlWithKey f z (NEMap k v m) = M.foldlWithKey f (f z k v) m-{-# INLINE foldlWithKey #-}---- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is--- evaluated before using the result in the next application. This--- function is strict in the starting value.-foldlWithKey' :: (a -> k -> b -> a) -> a -> NEMap k b -> a-foldlWithKey' f z (NEMap k v m) = M.foldlWithKey' f x m- where- !x = f z k v-{-# INLINE foldlWithKey' #-}---- | /O(n)/. Return all keys of the map in ascending order.------ > keys (fromList ((5,"a") :| [(3,"b")])) == (3 :| [5])-keys :: NEMap k a -> NonEmpty k-keys (NEMap k _ m) = k :| M.keys m-{-# INLINE keys #-}---- | /O(n)/. An alias for 'toAscList'. Return all key\/value pairs in the map--- in ascending key order.------ > assocs (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])-assocs :: NEMap k a -> NonEmpty (k, a)-assocs = toList-{-# INLINE assocs #-}---- | /O(n)/. The non-empty set of all keys of the map.------ > keysSet (fromList ((5,"a") :| [(3,"b")])) == Data.Set.NonEmpty.fromList (3 :| [5])-keysSet :: NEMap k a -> NESet k-keysSet (NEMap k _ m) = NESet k (M.keysSet m)-{-# INLINE keysSet #-}---- | /O(n)/. Map a function over all values in the map.------ > let f key x = (show key) ++ ":" ++ x--- > mapWithKey f (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "3:b") :| [(5, "5:a")])-mapWithKey :: (k -> a -> b) -> NEMap k a -> NEMap k b-mapWithKey f (NEMap k v m) = NEMap k (f k v) (M.mapWithKey f m)-{-# NOINLINE [1] mapWithKey #-}--{-# RULES-"mapWithKey/mapWithKey" forall f g xs.- mapWithKey f (mapWithKey g xs) =- mapWithKey (\k a -> f k (g k a)) xs-"mapWithKey/map" forall f g xs.- mapWithKey f (map g xs) =- mapWithKey (\k a -> f k (g a)) xs-"map/mapWithKey" forall f g xs.- map f (mapWithKey g xs) =- mapWithKey (\k a -> f (g k a)) xs- #-}---- | /O(n)/. Convert the map to a list of key\/value pairs where the keys are--- in ascending order.------ > toAscList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])-toAscList :: NEMap k a -> NonEmpty (k, a)-toAscList = toList-{-# INLINE toAscList #-}---- | /O(n)/. Convert the map to a list of key\/value pairs where the keys--- are in descending order.------ > toDescList (fromList ((5,"a") :| [(3,"b")])) == ((5,"a") :| [(3,"b")])-toDescList :: NEMap k a -> NonEmpty (k, a)-toDescList (NEMap k0 v0 m) = M.foldlWithKey' go ((k0, v0) :| []) m- where- go xs k v = (k, v) NE.<| xs-{-# INLINE toDescList #-}---- | /O(log n)/. Convert a 'Map' into an 'NEMap' by adding a key-value--- pair. Because of this, we know that the map must have at least one--- element, and so therefore cannot be empty. If key is already present,--- will overwrite the original value.------ See 'insertMapMin' for a version that is constant-time if the new key is--- /strictly smaller than/ all keys in the original map.------ > insertMap 4 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])--- > insertMap 4 "c" Data.Map.empty == singleton 4 "c"-insertMap :: Ord k => k -> a -> Map k a -> NEMap k a-insertMap k v = withNonEmpty (singleton k v) (insert k v)-{-# INLINE insertMap #-}---- | /O(log n)/. Convert a 'Map' into an 'NEMap' by adding a key-value--- pair. Because of this, we know that the map must have at least one--- element, and so therefore cannot be empty. Uses a combining function--- with the new value as the first argument if the key is already present.------ > insertMapWith (++) 4 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])--- > insertMapWith (++) 5 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"ca")])-insertMapWith ::- Ord k =>- (a -> a -> a) ->- k ->- a ->- Map k a ->- NEMap k a-insertMapWith f k v = withNonEmpty (singleton k v) (insertWith f k v)-{-# INLINE insertMapWith #-}---- | /O(log n)/. Convert a 'Map' into an 'NEMap' by adding a key-value--- pair. Because of this, we know that the map must have at least one--- element, and so therefore cannot be empty. Uses a combining function--- with the key and new value as the first and second arguments if the key--- is already present.------ > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value--- > insertWithKey f 5 "xxx" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "5:xxx|a")])--- > insertWithKey f 7 "xxx" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])--- > insertWithKey f 5 "xxx" Data.Map.empty == singleton 5 "xxx"-insertMapWithKey ::- Ord k =>- (k -> a -> a -> a) ->- k ->- a ->- Map k a ->- NEMap k a-insertMapWithKey f k v = withNonEmpty (singleton k v) (insertWithKey f k v)-{-# INLINE insertMapWithKey #-}---- | /O(1)/ Convert a 'Map' into an 'NEMap' by adding a key-value pair--- where the key is /strictly less than/ all keys in the input map. The--- keys in the original map must all be /strictly greater than/ the new--- key. /The precondition is not checked./------ > insertMapMin 2 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((2,"c") :| [(3,"b"), (5,"a")])--- > valid (insertMapMin 2 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == True--- > valid (insertMapMin 7 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False--- > valid (insertMapMin 3 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False-insertMapMin ::- k ->- a ->- Map k a ->- NEMap k a-insertMapMin = NEMap-{-# INLINE insertMapMin #-}---- | /O(log n)/ Convert a 'Map' into an 'NEMap' by adding a key-value pair--- where the key is /strictly greater than/ all keys in the input map. The--- keys in the original map must all be /strictly less than/ the new--- key. /The precondition is not checked./------ While this has the same asymptotics as 'insertMap', it saves a constant--- factor for key comparison (so may be helpful if comparison is expensive)--- and also does not require an 'Ord' instance for the key type.------ > insertMap 7 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"a"), (7,"c")])--- > valid (insertMap 7 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == True--- > valid (insertMap 2 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False--- > valid (insertMap 5 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False-insertMapMax ::- k ->- a ->- Map k a ->- NEMap k a-insertMapMax k v = withNonEmpty (singleton k v) go- where- go (NEMap k0 v0 m0) = NEMap k0 v0 . insertMaxMap k v $ m0-{-# INLINE insertMapMax #-}---- | /O(log n)/. Insert a new key and value in the map.--- If the key is already present in the map, the associated value is--- replaced with the supplied value. 'insert' is equivalent to--- @'insertWith' 'const'@.------ See 'insertMap' for a version where the first argument is a 'Map'.------ > insert 5 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'x')])--- > insert 7 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'a'), (7, 'x')])-insert ::- Ord k =>- k ->- a ->- NEMap k a ->- NEMap k a-insert k v n@(NEMap k0 v0 m) = case compare k k0 of- LT -> NEMap k v . toMap $ n- EQ -> NEMap k v m- GT -> NEMap k0 v0 . M.insert k v $ m-{-# INLINE insert #-}---- | /O(log n)/. Insert with a function, combining key, new value and old--- value. @'insertWithKey' f key value mp@ will insert the pair (key,--- value) into @mp@ if key does not exist in the map. If the key does--- exist, the function will insert the pair @(key,f key new_value--- old_value)@. Note that the key passed to f is the same key passed to--- 'insertWithKey'.------ See 'insertMapWithKey' for a version where the first argument is a 'Map'.------ > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value--- > insertWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:xxx|a")])--- > insertWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])-insertWithKey ::- Ord k =>- (k -> a -> a -> a) ->- k ->- a ->- NEMap k a ->- NEMap k a-insertWithKey f k v n@(NEMap k0 v0 m) = case compare k k0 of- LT -> NEMap k v . toMap $ n- EQ -> NEMap k (f k v v0) m- GT -> NEMap k0 v0 $ M.insertWithKey f k v m-{-# INLINE insertWithKey #-}---- | /O(log n)/. Combines insert operation with old value retrieval. The--- expression (@'insertLookupWithKey' f k x map@) is a pair where the first--- element is equal to (@'lookup' k map@) and the second element equal to--- (@'insertWithKey' f k x map@).------ > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value--- > insertLookupWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "5:xxx|a")]))--- > insertLookupWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "xxx")]))------ This is how to define @insertLookup@ using @insertLookupWithKey@:------ > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t--- > insertLookup 5 "x" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "x")]))--- > insertLookup 7 "x" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "x")]))-insertLookupWithKey ::- Ord k =>- (k -> a -> a -> a) ->- k ->- a ->- NEMap k a ->- (Maybe a, NEMap k a)-insertLookupWithKey f k v n@(NEMap k0 v0 m) = case compare k k0 of- LT -> (Nothing, NEMap k v . toMap $ n)- EQ -> (Just v, NEMap k (f k v v0) m)- GT -> NEMap k0 v0 <$> M.insertLookupWithKey f k v m-{-# INLINE insertLookupWithKey #-}---- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs--- with a combining function. See also 'fromAscListWith'.------ > fromListWith (++) ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "ab") :| [(5, "aba")])-fromListWith ::- Ord k =>- (a -> a -> a) ->- NonEmpty (k, a) ->- NEMap k a-fromListWith f = fromListWithKey (const f)-{-# INLINE fromListWith #-}---- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs--- with a combining function. See also 'fromAscListWithKey'.------ > let f k a1 a2 = (show k) ++ a1 ++ a2--- > fromListWithKey f ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "3ab") :| [(5, "5a5ba")])-fromListWithKey ::- Ord k =>- (k -> a -> a -> a) ->- NonEmpty (k, a) ->- NEMap k a-fromListWithKey f ((k0, v0) :| xs) = F.foldl' go (singleton k0 v0) xs- where- go m (k, v) = insertWithKey f k v m- {-# INLINE go #-}-{-# INLINE fromListWithKey #-}---- | /O(n)/. Build a map from an ascending non-empty list in linear time.--- /The precondition (input list is ascending) is not checked./------ > fromAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])--- > fromAscList ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "b")])--- > valid (fromAscList ((3,"b") :| [(5,"a"), (5,"b")])) == True--- > valid (fromAscList ((5,"a") :| [(3,"b"), (5,"b")])) == False-fromAscList ::- Eq k =>- NonEmpty (k, a) ->- NEMap k a-fromAscList = fromDistinctAscList . combineEq-{-# INLINE fromAscList #-}---- | /O(n)/. Build a map from an ascending non-empty list in linear time--- with a combining function for equal keys. /The precondition (input list--- is ascending) is not checked./------ > fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "ba")])--- > valid (fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b"))]) == True--- > valid (fromAscListWith (++) ((5,"a") :| [(3,"b"), (5,"b"))]) == False-fromAscListWith ::- Eq k =>- (a -> a -> a) ->- NonEmpty (k, a) ->- NEMap k a-fromAscListWith f = fromAscListWithKey (const f)-{-# INLINE fromAscListWith #-}---- | /O(n)/. Build a map from an ascending non-empty list in linear time--- with a combining function for equal keys. /The precondition (input list--- is ascending) is not checked./------ > let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2--- > fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")]) == fromList ((3, "b") :| [(5, "5:b5:ba")])--- > valid (fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")])) == True--- > valid (fromAscListWithKey f ((5,"a") :| [(3,"b"), (5,"b"), (5,"b")])) == False-fromAscListWithKey ::- Eq k =>- (k -> a -> a -> a) ->- NonEmpty (k, a) ->- NEMap k a-fromAscListWithKey f = fromDistinctAscList . combineEqWith f-{-# INLINE fromAscListWithKey #-}---- | /O(n)/. Build a map from an ascending non-empty list of distinct--- elements in linear time. /The precondition is not checked./------ > fromDistinctAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])--- > valid (fromDistinctAscList ((3,"b") :| [(5,"a")])) == True--- > valid (fromDistinctAscList ((3,"b") :| [(5,"a"), (5,"b")])) == False-fromDistinctAscList :: NonEmpty (k, a) -> NEMap k a-fromDistinctAscList ((k, v) :| xs) =- insertMapMin k v- . M.fromDistinctAscList- $ xs-{-# INLINE fromDistinctAscList #-}---- | /O(n)/. Build a map from a descending non-empty list in linear time.--- /The precondition (input list is descending) is not checked./------ > fromDescList ((5,"a") :| [(3,"b")]) == fromList ((3, "b") :| [(5, "a")])--- > fromDescList ((5,"a") :| [(5,"b"), (3,"b")]) == fromList ((3, "b") :| [(5, "b")])--- > valid (fromDescList ((5,"a") :| [(5,"b"), (3,"b")])) == True--- > valid (fromDescList ((5,"a") :| [(3,"b"), (5,"b")])) == False-fromDescList ::- Eq k =>- NonEmpty (k, a) ->- NEMap k a-fromDescList = fromDistinctDescList . combineEq-{-# INLINE fromDescList #-}---- | /O(n)/. Build a map from a descending non-empty list in linear time--- with a combining function for equal keys. /The precondition (input list--- is descending) is not checked./------ > fromDescListWith (++) ((5,"a") :| [(5,"b"), (3,"b")]) == fromList ((3, "b") :| [(5, "ba")])--- > valid (fromDescListWith (++) ((5,"a") :| [(5,"b"), (3,"b")])) == True--- > valid (fromDescListWith (++) ((5,"a") :| [(3,"b"), (5,"b")])) == False-fromDescListWith ::- Eq k =>- (a -> a -> a) ->- NonEmpty (k, a) ->- NEMap k a-fromDescListWith f = fromDescListWithKey (const f)-{-# INLINE fromDescListWith #-}---- | /O(n)/. Build a map from a descending non-empty list in linear time--- with a combining function for equal keys. /The precondition (input list--- is descending) is not checked./------ > let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2--- > fromDescListWithKey f ((5,"a") :| [(5,"b"), (5,"b"), (3,"b")]) == fromList ((3, "b") :| [(5, "5:b5:ba")])--- > valid (fromDescListWithKey f ((5,"a") :| [(5,"b"), (5,"b"), (3,"b")])) == True--- > valid (fromDescListWithKey f ((5,"a") :| [(3,"b"), (5,"b"), (5,"b")])) == False-fromDescListWithKey ::- Eq k =>- (k -> a -> a -> a) ->- NonEmpty (k, a) ->- NEMap k a-fromDescListWithKey f = fromDistinctDescList . combineEqWith f-{-# INLINE fromDescListWithKey #-}---- | /O(n)/. Build a map from a descending list of distinct elements in linear time.--- /The precondition is not checked./------ > fromDistinctDescList ((5,"a") :| [(3,"b")]) == fromList ((3, "b") :| [(5, "a")])--- > valid (fromDistinctDescList ((5,"a") :| [(3,"b")])) == True--- > valid (fromDistinctDescList ((5,"a") :| [(5,"b"), (3,"b")])) == False------ @since 0.5.8-fromDistinctDescList :: NonEmpty (k, a) -> NEMap k a-fromDistinctDescList ((k, v) :| xs) =- insertMapMax k v- . M.fromDistinctDescList- $ xs-{-# INLINE fromDistinctDescList #-}---- | /O(log n)/. Delete a key and its value from the non-empty map.--- A potentially empty map ('Map') is returned, since this might delete the--- last item in the 'NEMap'. When the key is not a member of the map, is--- equivalent to 'toMap'.------ > delete 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"--- > delete 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.Singleton [(3, "b"), (5, "a")]-delete :: Ord k => k -> NEMap k a -> Map k a-delete k n@(NEMap k0 v m) = case compare k k0 of- LT -> toMap n- EQ -> m- GT -> insertMinMap k0 v . M.delete k $ m-{-# INLINE delete #-}---- | /O(log n)/. Delete a key and its value from the non-empty map, returning--- 'Nothing' if the result would be empty.------ This is more efficient than @'nonEmptyMap' . 'delete' k@ because it avoids--- converting the known-minimum representation back through 'Map' when the--- deleted key is not the minimum.------ @since 0.3.6.0-deleteMaybe :: Ord k => k -> NEMap k a -> Maybe (NEMap k a)-deleteMaybe k n@(NEMap k0 v m) = case compare k k0 of- LT -> Just n- EQ -> nonEmptyMap m- GT -> Just . NEMap k0 v . M.delete k $ m-{-# INLINE deleteMaybe #-}---- | /O(log n)/. Update a value at a specific key with the result of the--- provided function. When the key is not a member of the map, the original--- map is returned.------ > adjust ("new " ++) 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "new a")])--- > adjust ("new " ++) 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])-adjust ::- Ord k =>- (a -> a) ->- k ->- NEMap k a ->- NEMap k a-adjust f = adjustWithKey (const f)-{-# INLINE adjust #-}---- | /O(log n)/. Adjust a value at a specific key. When the key is not--- a member of the map, the original map is returned.------ > let f key x = (show key) ++ ":new " ++ x--- > adjustWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:new a")])--- > adjustWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])-adjustWithKey ::- Ord k =>- (k -> a -> a) ->- k ->- NEMap k a ->- NEMap k a-adjustWithKey f k n@(NEMap k0 v m) = case compare k k0 of- LT -> n- EQ -> NEMap k0 (f k0 v) m- GT -> NEMap k0 v . M.adjustWithKey f k $ m-{-# INLINE adjustWithKey #-}---- | /O(log n)/. The expression (@'update' f k map@) updates the value @x@--- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is--- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.------ Returns a potentially empty map ('Map'), because we can't know ahead of--- time if the function returns 'Nothing' and deletes the final item in the--- 'NEMap'.------ > let f x = if x == "a" then Just "new a" else Nothing--- > update f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "new a")]--- > update f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a")]--- > update f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"-update ::- Ord k =>- (a -> Maybe a) ->- k ->- NEMap k a ->- Map k a-update f = updateWithKey (const f)-{-# INLINE update #-}---- | /O(log n)/. The expression (@'updateWithKey' f k map@) updates the--- value @x@ at @k@ (if it is in the map). If (@f k x@) is 'Nothing',--- the element is deleted. If it is (@'Just' y@), the key @k@ is bound--- to the new value @y@.------ Returns a potentially empty map ('Map'), because we can't know ahead of--- time if the function returns 'Nothing' and deletes the final item in the--- 'NEMap'.------ > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing--- > updateWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "5:new a")]--- > updateWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a")]--- > updateWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"-updateWithKey ::- Ord k =>- (k -> a -> Maybe a) ->- k ->- NEMap k a ->- Map k a-updateWithKey f k n@(NEMap k0 v m) = case compare k k0 of- LT -> toMap n- EQ -> maybe m (flip (insertMinMap k0) m) . f k0 $ v- GT -> insertMinMap k0 v . M.updateWithKey f k $ m-{-# INLINE updateWithKey #-}---- | /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 a potentially empty map ('Map') in the case that we delete the--- final key of a singleton map.------ > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing--- > updateLookupWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == (Just "5:new a", Data.Map.fromList ((3, "b") :| [(5, "5:new a")]))--- > updateLookupWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == (Nothing, Data.Map.fromList ((3, "b") :| [(5, "a")]))--- > updateLookupWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == (Just "b", Data.Map.singleton 5 "a")-updateLookupWithKey ::- Ord k =>- (k -> a -> Maybe a) ->- k ->- NEMap k a ->- (Maybe a, Map k a)-updateLookupWithKey f k n@(NEMap k0 v m) = case compare k k0 of- LT -> (Nothing, toMap n)- EQ ->- let u = f k0 v- in (u <|> Just v, maybe m (flip (insertMinMap k0) m) u)- GT -> fmap (insertMinMap k0 v) . M.updateLookupWithKey f k $ m-{-# INLINE updateLookupWithKey #-}---- | /O(log n)/. The expression (@'alter' f k map@) alters the value @x@ at--- @k@, or absence thereof. 'alter' can be used to insert, delete, or--- update a value in a 'Map'. In short : @Data.Map.lookup k ('alter'--- f k m) = f ('lookup' k m)@.------ Returns a potentially empty map ('Map'), because we can't know ahead of--- time if the function returns 'Nothing' and deletes the final item in the--- 'NEMap'.------ See 'alterF'' for a version that disallows deletion, and so therefore--- can return 'NEMap'.------ > let f _ = Nothing--- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a")]--- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"--- >--- > let f _ = Just "c"--- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a"), (7, "c")]--- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "c")]-alter ::- Ord k =>- (Maybe a -> Maybe a) ->- k ->- NEMap k a ->- Map k a-alter f k n@(NEMap k0 v m) = case compare k k0 of- LT -> maybe id (insertMinMap k) (f Nothing) (toMap n)- EQ -> maybe id (insertMinMap k0) (f (Just v)) m- GT -> insertMinMap k0 v . M.alter f k $ m-{-# INLINE alter #-}---- | /O(log n)/. The expression (@'alterF' f k map@) alters the value @x@--- at @k@, or absence thereof. 'alterF' can be used to inspect, insert,--- delete, or update a value in a 'Map'. In short: @Data.Map.lookup--- k \<$\> 'alterF' f k m = f ('lookup' k m)@.------ Example:------ @--- interactiveAlter :: Int -> NEMap Int String -> IO (Map Int String)--- interactiveAlter k m = alterF f k m where--- f Nothing = do--- putStrLn $ show k ++--- " was not found in the map. Would you like to add it?"--- getUserResponse1 :: IO (Maybe String)--- f (Just old) = do--- putStrLn $ "The key is currently bound to " ++ show old ++--- ". Would you like to change or delete it?"--- getUserResponse2 :: IO (Maybe String)--- @------ Like @Data.Map.alterF@ for 'Map', 'alterF' can be considered--- to be a unifying generalization of 'lookup' and 'delete'; however, as--- a constrast, it cannot be used to implement 'insert', because it must--- return a 'Map' instead of an 'NEMap' (because the function might delete--- the final item in the 'NEMap'). When used with trivial functors like--- 'Identity' and 'Const', it is often slightly slower than--- specialized 'lookup' and 'delete'. However, when the functor is--- non-trivial and key comparison is not particularly cheap, it is the--- fastest way.------ See 'alterF'' for a version that disallows deletion, and so therefore--- can return 'NEMap' and be used to implement 'insert'------ Note on rewrite rules:------ This module includes GHC rewrite rules to optimize 'alterF' for--- the 'Const' and 'Identity' functors. In general, these rules--- improve performance. The sole exception is that when using--- 'Identity', deleting a key that is already absent takes longer--- than it would without the rules. If you expect this to occur--- a very large fraction of the time, you might consider using a--- private copy of the 'Identity' type.------ Note: Unlike @Data.Map.alterF@ for 'Map', 'alterF' is /not/ a flipped--- version of the 'Control.Lens.At.at' combinator from "Control.Lens.At".--- However, it match the shape expected from most functions expecting--- lenses, getters, and setters, so can be thought of as a "psuedo-lens",--- with virtually the same practical applications as a legitimate lens.-alterF ::- (Ord k, Functor f) =>- (Maybe a -> f (Maybe a)) ->- k ->- NEMap k a ->- f (Map k a)-alterF f k n@(NEMap k0 v m) = case compare k k0 of- LT -> flip (maybe id (insertMinMap k)) (toMap n) <$> f Nothing- EQ -> flip (maybe id (insertMinMap k0)) m <$> f (Just v)- GT -> insertMinMap k0 v <$> M.alterF f k m-{-# INLINEABLE [2] alterF #-}---- if f ~ Const b, it's a lookup-{-# RULES-"alterF/Const" forall k (f :: Maybe a -> Const b (Maybe a)).- alterF f k =- Const . getConst . f . lookup k- #-}---- if f ~ Identity, it's an 'alter'-{-# RULES-"alterF/Identity" forall k (f :: Maybe a -> Identity (Maybe a)).- alterF f k =- Identity . alter (runIdentity . f) k- #-}---- | /O(log n)/. Variant of 'alter' that disallows deletion. Allows us to--- guarantee that the result is also a non-empty Map.-alter' ::- Ord k =>- (Maybe a -> a) ->- k ->- NEMap k a ->- NEMap k a-alter' f k n@(NEMap k0 v m) = case compare k k0 of- LT -> NEMap k (f Nothing) . toMap $ n- EQ -> NEMap k0 (f (Just v)) m- GT -> NEMap k0 v . M.alter (Just . f) k $ m-{-# INLINE alter' #-}---- | /O(log n)/. Variant of 'alterF' that disallows deletion. Allows us to--- guarantee that the result is also a non-empty Map.------ Like @Data.Map.alterF@ for 'Map', can be used to generalize and unify--- 'lookup' and 'insert'. However, because it disallows deletion, it--- cannot be used to implement 'delete'.------ See 'alterF' for usage information and caveats.------ Note: Neither 'alterF' nor 'alterF'' can be considered flipped versions--- of the 'Control.Lens.At.at' combinator from "Control.Lens.At". However,--- this can match the shape expected from most functions expecting lenses,--- getters, and setters, so can be thought of as a "psuedo-lens", with--- virtually the same practical applications as a legitimate lens.------ __WARNING__: The rewrite rule for 'Identity' exposes an inconsistency in--- undefined behavior for "Data.Map". @Data.Map.alterF@ will actually--- /maintain/ the original key in the map when used with 'Identity';--- however, @Data.Map.insertWith@ will /replace/ the orginal key in the--- map. The rewrite rule for 'alterF'' has chosen to be faithful to--- @Data.Map.insertWith@, and /not/ @Data.Map.alterF@, for the sake of--- a cleaner implementation.-alterF' ::- (Ord k, Functor f) =>- (Maybe a -> f a) ->- k ->- NEMap k a ->- f (NEMap k a)-alterF' f k n@(NEMap k0 v m) = case compare k k0 of- LT -> flip (NEMap k) (toMap n) <$> f Nothing- EQ -> flip (NEMap k0) m <$> f (Just v)- GT -> NEMap k0 v <$> M.alterF (fmap Just . f) k m-{-# INLINEABLE [2] alterF' #-}---- if f ~ Const b, it's a lookup-{-# RULES-"alterF'/Const" forall k (f :: Maybe a -> Const b a).- alterF' f k =- Const . getConst . f . lookup k- #-}---- if f ~ Identity, it's an insertWith-{-# RULES-"alterF'/Identity" forall k (f :: Maybe a -> Identity a).- alterF' f k =- Identity . insertWith (\_ -> runIdentity . f . Just) k (runIdentity (f Nothing))- #-}---- | /O(n)/. Traverse keys\/values and collect the 'Just' results.------ Returns a potentially empty map ('Map'), our function might return--- 'Nothing' on every item in the 'NEMap'.------ /Use 'traverseMaybeWithKey1'/ whenever possible (if your 'Applicative'--- also has 'Apply' instance). This version is provided only for types--- that do not have 'Apply' instance, since 'Apply' is not at the moment--- (and might not ever be) an official superclass of 'Applicative'.-traverseMaybeWithKey ::- Applicative t =>- (k -> a -> t (Maybe b)) ->- NEMap k a ->- t (Map k b)-traverseMaybeWithKey f (NEMap k0 v m0) =- combine <$> f k0 v <*> M.traverseMaybeWithKey f m0- where- combine Nothing = id- combine (Just v') = insertMinMap k0 v'-{-# INLINE traverseMaybeWithKey #-}---- | /O(n)/. Traverse keys\/values and collect the 'Just' results.------ Returns a potentially empty map ('Map'), our function might return--- 'Nothing' on every item in the 'NEMap'.------ Is more general than 'traverseWithKey', since works with all 'Apply',--- and not just 'Applicative'.---- TODO: benchmark against M.maxView version-traverseMaybeWithKey1 ::- Apply t =>- (k -> a -> t (Maybe b)) ->- NEMap k a ->- t (Map k b)-traverseMaybeWithKey1 f (NEMap k0 v m0) = case runMaybeApply m1 of- Left m2 -> combine <$> f k0 v <.> m2- Right m2 -> (`combine` m2) <$> f k0 v- where- m1 = M.traverseMaybeWithKey (\k -> MaybeApply . Left . f k) m0- combine Nothing = id- combine (Just v') = insertMinMap k0 v'-{-# INLINE traverseMaybeWithKey1 #-}---- | /O(n)/. The function 'mapAccum' threads an accumulating argument--- through the map in ascending order of keys.------ > let f a b = (a ++ b, b ++ "X")--- > mapAccum f "Everything: " (fromList ((5,"a") :| [(3,"b")])) == ("Everything: ba", fromList ((3, "bX") :| [(5, "aX")]))-mapAccum ::- (a -> b -> (a, c)) ->- a ->- NEMap k b ->- (a, NEMap k c)-mapAccum f = mapAccumWithKey (\x _ -> f x)-{-# INLINE mapAccum #-}---- | /O(n)/. The function 'mapAccumWithKey' threads an accumulating--- argument through the map in ascending order of keys.------ > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")--- > mapAccumWithKey f "Everything:" (fromList ((5,"a") :| [(3,"b")])) == ("Everything: 3-b 5-a", fromList ((3, "bX") :| [(5, "aX")]))-mapAccumWithKey ::- (a -> k -> b -> (a, c)) ->- a ->- NEMap k b ->- (a, NEMap k c)-mapAccumWithKey f z0 (NEMap k v m) = (z2, NEMap k v' m')- where- ~(z1, v') = f z0 k v- ~(z2, m') = M.mapAccumWithKey f z1 m-{-# INLINE mapAccumWithKey #-}---- | /O(n)/. The function 'mapAccumRWithKey' threads an accumulating--- argument through the map in descending order of keys.-mapAccumRWithKey ::- (a -> k -> b -> (a, c)) ->- a ->- NEMap k b ->- (a, NEMap k c)-mapAccumRWithKey f z0 (NEMap k v m) = (z2, NEMap k v' m')- where- ~(z1, m') = M.mapAccumRWithKey f z0 m- ~(z2, v') = f z1 k v-{-# INLINE mapAccumRWithKey #-}---- TODO: what other situations can we take advantage of lazy tuple pattern--- matching?---- | /O(n*log n)/.--- @'mapKeys' 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 value at the greatest of the--- original keys is retained.------ While the size of the result map may be smaller than the input map, the--- output map is still guaranteed to be non-empty if the input map is--- non-empty.------ > mapKeys (+ 1) (fromList ((5,"a") :| [(3,"b")])) == fromList ((4, "b") :| [(6, "a")])--- > mapKeys (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "c"--- > mapKeys (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "c"-mapKeys ::- Ord k2 =>- (k1 -> k2) ->- NEMap k1 a ->- NEMap k2 a-mapKeys f (NEMap k0 v0 m) =- fromListWith const- . ((f k0, v0) :|)- . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []- $ m-{-# INLINEABLE mapKeys #-}---- | /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@. The value at the greater of the two original keys--- is used as the first argument to @c@.------ While the size of the result map may be smaller than the input map, the--- output map is still guaranteed to be non-empty if the input map is--- non-empty.------ > mapKeysWith (++) (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "cdab"--- > mapKeysWith (++) (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "cdab"-mapKeysWith ::- Ord k2 =>- (a -> a -> a) ->- (k1 -> k2) ->- NEMap k1 a ->- NEMap k2 a-mapKeysWith c f (NEMap k0 v0 m) =- fromListWith c- . ((f k0, v0) :|)- . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []- $ m-{-# INLINEABLE mapKeysWith #-}---- | /O(n)/.--- @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@--- is strictly monotonic.--- 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]--- > ==> mapKeysMonotonic f s == mapKeys f s--- > where ls = keys s------ This means that @f@ maps distinct original keys to distinct resulting keys.--- This function has better performance than 'mapKeys'.------ While the size of the result map may be smaller than the input map, the--- output map is still guaranteed to be non-empty if the input map is--- non-empty.------ > mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")])) == fromList ((6, "b") :| [(10, "a")])--- > valid (mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")]))) == True--- > valid (mapKeysMonotonic (\ _ -> 1) (fromList ((5,"a") :| [(3,"b")]))) == False-mapKeysMonotonic ::- (k1 -> k2) ->- NEMap k1 a ->- NEMap k2 a-mapKeysMonotonic f (NEMap k v m) =- NEMap (f k) v- . M.mapKeysMonotonic f- $ m-{-# INLINE mapKeysMonotonic #-}---- | /O(n)/. Filter all values that satisfy the predicate.------ Returns a potentially empty map ('Map'), because we could--- potentailly filter out all items in the original 'NEMap'.------ > filter (> "a") (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"--- > filter (> "x") (fromList ((5,"a") :| [(3,"b")])) == Data.Map.empty--- > filter (< "a") (fromList ((5,"a") :| [(3,"b")])) == Data.Map.empty-filter ::- (a -> Bool) ->- NEMap k a ->- Map k a-filter f (NEMap k v m)- | f v = insertMinMap k v . M.filter f $ m- | otherwise = M.filter f m-{-# INLINE filter #-}---- | /O(n)/. Filter all keys\/values that satisfy the predicate.------ Returns a potentially empty map ('Map'), because we could--- potentailly filter out all items in the original 'NEMap'.------ > filterWithKey (\k _ -> k > 4) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"-filterWithKey ::- (k -> a -> Bool) ->- NEMap k a ->- Map k a-filterWithKey f (NEMap k v m)- | f k v = insertMinMap k v . M.filterWithKey f $ m- | otherwise = M.filterWithKey f m-{-# INLINE filterWithKey #-}---- | /O(m*log(n\/m + 1)), m <= n/. Restrict an 'NEMap' to only those keys--- found in a 'Data.Set.Set'.------ @--- m \`restrictKeys\` s = 'filterWithKey' (\k _ -> k ``Set.member`` s) m--- m \`restrictKeys\` s = m ``intersection`` 'fromSet' (const ()) s--- @-restrictKeys ::- Ord k =>- NEMap k a ->- Set k ->- Map k a-restrictKeys n@(NEMap k v m) xs = case S.minView xs of- Nothing -> M.empty- Just (y, ys) -> case compare k y of- -- k is not in xs- LT -> m `M.restrictKeys` xs- -- k and y are a part of the result- EQ -> insertMinMap k v $ m `M.restrictKeys` ys- -- y is not in m- GT -> toMap n `M.restrictKeys` ys-{-# INLINE restrictKeys #-}---- | /O(m*log(n\/m + 1)), m <= n/. Remove all keys in a 'Data.Set.Set' from--- an 'NEMap'.------ @--- m \`withoutKeys\` s = 'filterWithKey' (\k _ -> k ``Set.notMember`` s) m--- m \`withoutKeys\` s = m ``difference`` 'fromSet' (const ()) s--- @-withoutKeys ::- Ord k =>- NEMap k a ->- Set k ->- Map k a-withoutKeys n@(NEMap k v m) xs = case S.minView xs of- Nothing -> toMap n- Just (y, ys) -> case compare k y of- -- k is not in xs, so cannot be deleted- LT -> insertMinMap k v $ m `M.withoutKeys` xs- -- y deletes k, and only k- EQ -> m `M.withoutKeys` ys- -- y is not in n, so cannot delete anything, so we can just difference n and ys- GT -> toMap n `M.withoutKeys` ys-{-# INLINE withoutKeys #-}---- | /O(n)/. Partition the map according to a predicate.------ Returns a 'These' with potentially two non-empty maps:------ * @'This' n1@ means that the predicate was true for all items.--- * @'That' n2@ means that the predicate was false for all items.--- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the--- predicate) and @n2@ (all of the items that were false for the--- predicate).------ See also 'split'.------ > partition (> "a") (fromList ((5,"a") :| [(3,"b")])) == These (singleton 3 "b") (singleton 5 "a")--- > partition (< "x") (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))--- > partition (> "x") (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))-partition ::- (a -> Bool) ->- NEMap k a ->- These (NEMap k a) (NEMap k a)-partition f = partitionWithKey (const f)-{-# INLINE partition #-}---- | /O(n)/. Partition the map according to a predicate.------ Returns a 'These' with potentially two non-empty maps:------ * @'This' n1@ means that the predicate was true for all items,--- returning the original map.--- * @'That' n2@ means that the predicate was false for all items,--- returning the original map.--- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the--- predicate) and @n2@ (all of the items that were false for the--- predicate).------ See also 'split'.------ > partitionWithKey (\ k _ -> k > 3) (fromList ((5,"a") :| [(3,"b")])) == These (singleton 5 "a") (singleton 3 "b")--- > partitionWithKey (\ k _ -> k < 7) (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))--- > partitionWithKey (\ k _ -> k > 7) (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))-partitionWithKey ::- (k -> a -> Bool) ->- NEMap k a ->- These (NEMap k a) (NEMap k a)-partitionWithKey f n@(NEMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing)- | f k v -> This n- | otherwise -> That n- (Just n1, Nothing)- | f k v -> This n- | otherwise -> These n1 (singleton k v)- (Nothing, Just n2)- | f k v -> These (singleton k v) n2- | otherwise -> That n- (Just n1, Just n2)- | f k v -> These (insertMapMin k v m1) n2- | otherwise -> These n1 (insertMapMin k v m2)- where- (m1, m2) = M.partitionWithKey f m0-{-# INLINEABLE partitionWithKey #-}---- | /O(log n)/. Take while a predicate on the keys holds.--- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,--- @j \< k ==\> p j \>= p k@. See note at 'spanAntitone'.------ Returns a potentially empty map ('Map'), because the predicate might--- fail on the first input.------ @--- takeWhileAntitone p = Data.Map.fromDistinctAscList . Data.List.takeWhile (p . fst) . Data.Foldable.toList--- takeWhileAntitone p = 'filterWithKey' (\k _ -> p k)--- @-takeWhileAntitone ::- (k -> Bool) ->- NEMap k a ->- Map k a-takeWhileAntitone f (NEMap k v m)- | f k = insertMinMap k v . M.takeWhileAntitone f $ m- | otherwise = M.empty-{-# INLINE takeWhileAntitone #-}---- | /O(log n)/. Drop while a predicate on the keys holds.--- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,--- @j \< k ==\> p j \>= p k@. See note at 'spanAntitone'.------ @--- dropWhileAntitone p = Data.Map.fromDistinctAscList . Data.List.dropWhile (p . fst) . Data.Foldable.toList--- dropWhileAntitone p = 'filterWithKey' (\k -> not (p k))--- @-dropWhileAntitone ::- (k -> Bool) ->- NEMap k a ->- Map k a-dropWhileAntitone f n@(NEMap k _ m)- | f k = M.dropWhileAntitone f m- | otherwise = toMap n-{-# INLINE dropWhileAntitone #-}---- | /O(log n)/. Divide a map at the point where a predicate on the keys stops holding.--- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,--- @j \< k ==\> p j \>= p k@.------ Returns a 'These' with potentially two non-empty maps:------ * @'This' n1@ means that the predicate never failed for any item,--- returning the original map.--- * @'That' n2@ means that the predicate failed for the first item,--- returning the original map.--- * @'These' n1 n2@ gives @n1@ (the map up to the point where the--- predicate on the keys stops holding) and @n2@ (the map starting from--- the point where the predicate stops holding)------ @--- spanAntitone p xs = partitionWithKey (\k _ -> p k) xs--- @------ Note: if @p@ is not actually antitone, then @spanAntitone@ will split the map--- at some /unspecified/ point where the predicate switches from holding to not--- holding (where the predicate is seen to hold before the first key and to fail--- after the last key).-spanAntitone ::- (k -> Bool) ->- NEMap k a ->- These (NEMap k a) (NEMap k a)-spanAntitone f n@(NEMap k v m0)- | f k = case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing) -> This n- (Just _, Nothing) -> This n- (Nothing, Just n2) -> These (singleton k v) n2- (Just _, Just n2) -> These (insertMapMin k v m1) n2- | otherwise = That n- where- (m1, m2) = M.spanAntitone f m0-{-# INLINEABLE spanAntitone #-}---- | /O(n)/. Map values and collect the 'Just' results.------ Returns a potentially empty map ('Map'), because the function could--- potentially return 'Nothing' on all items in the 'NEMap'.------ > let f x = if x == "a" then Just "new a" else Nothing--- > mapMaybe f (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "new a"-mapMaybe ::- (a -> Maybe b) ->- NEMap k a ->- Map k b-mapMaybe f = mapMaybeWithKey (const f)-{-# INLINE mapMaybe #-}---- | /O(n)/. Map keys\/values and collect the 'Just' results.------ Returns a potentially empty map ('Map'), because the function could--- potentially return 'Nothing' on all items in the 'NEMap'.------ > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing--- > mapMaybeWithKey f (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "key : 3"-mapMaybeWithKey ::- (k -> a -> Maybe b) ->- NEMap k a ->- Map k b-mapMaybeWithKey f (NEMap k v m) = maybe id (insertMinMap k) (f k v) (M.mapMaybeWithKey f m)-{-# INLINE mapMaybeWithKey #-}---- | /O(n)/. Map values and separate the 'Left' and 'Right' results.------ Returns a 'These' with potentially two non-empty maps:------ * @'This' n1@ means that the results were all 'Left'.--- * @'That' n2@ means that the results were all 'Right'.--- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')--- and @n2@ (the map where the results were 'Right')------ > let f a = if a < "c" then Left a else Right a--- > mapEither f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))--- > == These (fromList ((3,"b") :| [(5,"a")])) (fromList ((1,"x") :| [(7,"z")]))--- >--- > mapEither (\ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))--- > == That (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))-mapEither ::- (a -> Either b c) ->- NEMap k a ->- These (NEMap k b) (NEMap k c)-mapEither f = mapEitherWithKey (const f)-{-# INLINE mapEither #-}---- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results.------ Returns a 'These' with potentially two non-empty maps:------ * @'This' n1@ means that the results were all 'Left'.--- * @'That' n2@ means that the results were all 'Right'.--- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')--- and @n2@ (the map where the results were 'Right')------ > let f k a = if k < 5 then Left (k * 2) else Right (a ++ a)--- > mapEitherWithKey f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))--- > == These (fromList ((1,2) :| [(3,6)])) (fromList ((5,"aa") :| [(7,"zz")]))--- >--- > mapEitherWithKey (\_ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))--- > == That (fromList ((1,"x") :| [(3,"b"), (5,"a"), (7,"z")]))-mapEitherWithKey ::- (k -> a -> Either b c) ->- NEMap k a ->- These (NEMap k b) (NEMap k c)-mapEitherWithKey f (NEMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing) -> case f k v of- Left v' -> This (singleton k v')- Right v' -> That (singleton k v')- (Just n1, Nothing) -> case f k v of- Left v' -> This (insertMapMin k v' m1)- Right v' -> These n1 (singleton k v')- (Nothing, Just n2) -> case f k v of- Left v' -> These (singleton k v') n2- Right v' -> That (insertMapMin k v' m2)- (Just n1, Just n2) -> case f k v of- Left v' -> These (insertMapMin k v' m1) n2- Right v' -> These n1 (insertMapMin k v' m2)- where- (m1, m2) = M.mapEitherWithKey f m0-{-# INLINEABLE mapEitherWithKey #-}---- | /O(log n)/. The expression (@'split' k map@) is potentially a 'These'--- containing up to two 'NEMap's based on splitting the map into maps--- containing items before and after the given key @k@. It will never--- return a map that contains @k@ itself.------ * 'Nothing' means that @k@ was the only key in the the original map,--- and so there are no items before or after it.--- * @'Just' ('This' n1)@ means @k@ was larger than or equal to all items--- in the map, and @n1@ is the entire original map (minus @k@, if it was--- present)--- * @'Just' ('That' n2)@ means @k@ was smaller than or equal to all--- items in the map, and @n2@ is the entire original map (minus @k@, if--- it was present)--- * @'Just' ('These' n1 n2)@ gives @n1@ (the map of all keys from the--- original map less than @k@) and @n2@ (the map of all keys from the--- original map greater than @k@)------ > split 2 (fromList ((5,"a") :| [(3,"b")])) == Just (That (fromList ((3,"b") :| [(5,"a")])) )--- > split 3 (fromList ((5,"a") :| [(3,"b")])) == Just (That (singleton 5 "a") )--- > split 4 (fromList ((5,"a") :| [(3,"b")])) == Just (These (singleton 3 "b") (singleton 5 "a"))--- > split 5 (fromList ((5,"a") :| [(3,"b")])) == Just (This (singleton 3 "b") )--- > split 6 (fromList ((5,"a") :| [(3,"b")])) == Just (This (fromList ((3,"b") :| [(5,"a")])) )--- > split 5 (singleton 5 "a") == Nothing-split ::- Ord k =>- k ->- NEMap k a ->- Maybe (These (NEMap k a) (NEMap k a))-split k n@(NEMap k0 v m0) = case compare k k0 of- LT -> Just $ That n- EQ -> That <$> nonEmptyMap m0- GT -> Just $ case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing) -> This (singleton k0 v)- (Just _, Nothing) -> This (insertMapMin k0 v m1)- (Nothing, Just n2) -> These (singleton k0 v) n2- (Just _, Just n2) -> These (insertMapMin k0 v m1) n2- where- (m1, m2) = M.split k m0-{-# INLINEABLE split #-}---- | /O(log n)/. The expression (@'splitLookup' k map@) splits a map just--- like 'split' but also returns @'lookup' k map@, as the first field in--- the 'These':------ > splitLookup 2 (fromList ((5,"a") :| [(3,"b")])) == That (That (fromList ((3,"b") :| [(5,"a")])))--- > splitLookup 3 (fromList ((5,"a") :| [(3,"b")])) == These "b" (That (singleton 5 "a"))--- > splitLookup 4 (fromList ((5,"a") :| [(3,"b")])) == That (These (singleton 3 "b") (singleton 5 "a"))--- > splitLookup 5 (fromList ((5,"a") :| [(3,"b")])) == These "a" (This (singleton 3 "b"))--- > splitLookup 6 (fromList ((5,"a") :| [(3,"b")])) == That (This (fromList ((3,"b") :| [(5,"a")])))--- > splitLookup 5 (singleton 5 "a") == This "a"-splitLookup ::- Ord k =>- k ->- NEMap k a ->- These a (These (NEMap k a) (NEMap k a))-splitLookup k n@(NEMap k0 v0 m0) = case compare k k0 of- LT -> That . That $ n- EQ -> maybe (This v0) (These v0 . That) . nonEmptyMap $ m0- GT -> maybe That These v $ case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing) -> This (singleton k0 v0)- (Just _, Nothing) -> This (insertMapMin k0 v0 m1)- (Nothing, Just n2) -> These (singleton k0 v0) n2- (Just _, Just n2) -> These (insertMapMin k0 v0 m1) n2- where- (m1, v, m2) = M.splitLookup k m0-{-# INLINEABLE splitLookup #-}---- | /O(1)/. Decompose a map into pieces based on the structure of the--- underlying tree. This function is useful for consuming a map in--- parallel.------ No guarantee is made as to the sizes of the pieces; an internal, but--- deterministic process determines this. However, it is guaranteed that--- the pieces returned will be in ascending order (all elements in the--- first submap less than all elements in the second, and so on).------ Note that the current implementation does not return more than four--- submaps, but you should not depend on this behaviour because it can--- change in the future without notice.-splitRoot ::- NEMap k a ->- NonEmpty (NEMap k a)-splitRoot (NEMap k v m) =- singleton k v- :| Maybe.mapMaybe nonEmptyMap (M.splitRoot m)-{-# INLINE splitRoot #-}---- | /O(m*log(n\/m + 1)), m <= n/.--- This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).-isSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool-isSubmapOf = isSubmapOfBy (==)-{-# INLINE isSubmapOf #-}---- | /O(m*log(n\/m + 1)), m <= n/.--- The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if--- all keys in @t1@ are in tree @t2@, and when @f@ returns 'True' when--- applied to their respective values. For example, the following--- expressions are all 'True':------ > isSubmapOfBy (==) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))--- > isSubmapOfBy (<=) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))--- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (fromList (('a',1) :| [('b',2)]))------ But the following are all 'False':------ > isSubmapOfBy (==) (singleton 'a' 2) (fromList (('a',1) :| [('b',2)]))--- > isSubmapOfBy (<) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))--- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (singleton 'a' 1)-isSubmapOfBy ::- Ord k =>- (a -> b -> Bool) ->- NEMap k a ->- NEMap k b ->- Bool-isSubmapOfBy f (NEMap k v m0) (toMap -> m1) =- kvSub- && M.isSubmapOfBy f m0 m1- where- kvSub = case M.lookup k m1 of- Just v0 -> f v v0- Nothing -> False-{-# INLINE isSubmapOfBy #-}---- | /O(m*log(n\/m + 1)), m <= n/. Is this a proper submap? (ie. a submap--- but not equal). Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy'--- (==)@).-isProperSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool-isProperSubmapOf = isProperSubmapOfBy (==)-{-# INLINE isProperSubmapOf #-}---- | /O(m*log(n\/m + 1)), m <= n/. 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 values. For--- example, the following expressions are all 'True':------ > isProperSubmapOfBy (==) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))--- > isProperSubmapOfBy (<=) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))------ But the following are all 'False':------ > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (fromList ((1,1) :| [(2,2)]))--- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (singleton 1 1))--- > isProperSubmapOfBy (<) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))-isProperSubmapOfBy ::- Ord k =>- (a -> b -> Bool) ->- NEMap k a ->- NEMap k b ->- Bool-isProperSubmapOfBy f m1 m2 =- M.size (nemMap m1) < M.size (nemMap m2)- && isSubmapOfBy f m1 m2-{-# INLINE isProperSubmapOfBy #-}---- | /O(log n)/. Lookup the /index/ of a key, which is its zero-based index--- in the sequence sorted by keys. The index is a number from /0/ up to,--- but not including, the 'size' of the map.------ > isJust (lookupIndex 2 (fromList ((5,"a") :| [(3,"b")]))) == False--- > fromJust (lookupIndex 3 (fromList ((5,"a") :| [(3,"b")]))) == 0--- > fromJust (lookupIndex 5 (fromList ((5,"a") :| [(3,"b")]))) == 1--- > isJust (lookupIndex 6 (fromList ((5,"a") :| [(3,"b")]))) == False-lookupIndex ::- Ord k =>- k ->- NEMap k a ->- Maybe Int-lookupIndex k (NEMap k0 _ m) = case compare k k0 of- LT -> Nothing- EQ -> Just 0- GT -> (+ 1) <$> M.lookupIndex k m-{-# INLINE lookupIndex #-}---- | /O(log n)/. Return the /index/ of a key, which is its zero-based index--- in the sequence sorted by keys. The index is a number from /0/ up to,--- but not including, the 'size' of the map. Calls 'error' when the key is--- not a 'member' of the map.------ > findIndex 2 (fromList ((5,"a") :| [(3,"b")])) Error: element is not in the map--- > findIndex 3 (fromList ((5,"a") :| [(3,"b")])) == 0--- > findIndex 5 (fromList ((5,"a") :| [(3,"b")])) == 1--- > findIndex 6 (fromList ((5,"a") :| [(3,"b")])) Error: element is not in the map-findIndex ::- Ord k =>- k ->- NEMap k a ->- Int-findIndex k = fromMaybe e . lookupIndex k- where- e = error "NEMap.findIndex: element is not in the map"-{-# INLINE findIndex #-}---- | /O(log n)/. Retrieve an element by its /index/, i.e. by its zero-based--- index in the sequence sorted by keys. If the /index/ is out of range--- (less than zero, greater or equal to 'size' of the map), 'error' is--- called.------ > elemAt 0 (fromList ((5,"a") :| [(3,"b")])) == (3,"b")--- > elemAt 1 (fromList ((5,"a") :| [(3,"b")])) == (5, "a")--- > elemAt 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range-elemAt ::- Int ->- NEMap k a ->- (k, a)-elemAt 0 (NEMap k v _) = (k, v)-elemAt i (NEMap _ _ m) = M.elemAt (i - 1) m-{-# INLINEABLE elemAt #-}---- | /O(log n)/. Update the element at /index/, i.e. by its zero-based index in--- the sequence sorted by keys. If the /index/ is out of range (less than zero,--- greater or equal to 'size' of the map), 'error' is called.------ Returns a possibly empty map ('Map'), because the function might end up--- deleting the last key in the map. See 'adjustAt' for a version that--- disallows deletion, guaranteeing that the result is also a non-empty--- Map.------ > updateAt (\ _ _ -> Just "x") 0 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "x"), (5, "a")]--- > updateAt (\ _ _ -> Just "x") 1 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "x")]--- > updateAt (\ _ _ -> Just "x") 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range--- > updateAt (\ _ _ -> Just "x") (-1) (fromList ((5,"a") :| [(3,"b")])) Error: index out of range--- > updateAt (\_ _ -> Nothing) 0 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"--- > updateAt (\_ _ -> Nothing) 1 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"--- > updateAt (\_ _ -> Nothing) 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range--- > updateAt (\_ _ -> Nothing) (-1) (fromList ((5,"a") :| [(3,"b")])) Error: index out of range-updateAt ::- (k -> a -> Maybe a) ->- Int ->- NEMap k a ->- Map k a-updateAt f 0 (NEMap k v m) = maybe m (flip (insertMinMap k) m) $ f k v-updateAt f i (NEMap k v m) = insertMinMap k v . M.updateAt f (i - 1) $ m-{-# INLINEABLE updateAt #-}---- | /O(log n)/. Variant of 'updateAt' that disallows deletion. Allows us--- to guarantee that the result is also a non-empty Map.-adjustAt ::- (k -> a -> a) ->- Int ->- NEMap k a ->- NEMap k a-adjustAt f 0 (NEMap k0 v m) = NEMap k0 (f k0 v) m-adjustAt f i (NEMap k0 v m) =- NEMap k0 v- . M.updateAt (\k -> Just . f k) (i - 1)- $ m-{-# INLINEABLE adjustAt #-}---- | /O(log n)/. Delete the element at /index/, i.e. by its zero-based--- index in the sequence sorted by keys. If the /index/ is out of range--- (less than zero, greater or equal to 'size' of the map), 'error' is--- called.------ Returns a potentially empty map ('Map') because of the possibility of--- deleting the last item in a map.------ > deleteAt 0 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"--- > deleteAt 1 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"--- > deleteAt 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range--- > deleteAt (-1) (fromList ((5,"a") :| [(3,"b")])) Error: index out of range-deleteAt ::- Int ->- NEMap k a ->- Map k a-deleteAt 0 (NEMap _ _ m) = m-deleteAt i (NEMap k v m) = insertMinMap k v . M.deleteAt (i - 1) $ m-{-# INLINEABLE deleteAt #-}---- | Take a given number of entries in key order, beginning with the--- smallest keys.------ Returns a possibly empty map ('Map'), which can only happen if we call--- @take 0@.------ @--- take n = Data.Map.fromDistinctAscList . Data.List.NonEmpty.take n . 'toList'--- @-take ::- Int ->- NEMap k a ->- Map k a-take 0 NEMap{} = M.empty-take i (NEMap k v m) = insertMinMap k v . M.take (i - 1) $ m-{-# INLINEABLE take #-}---- | Drop a given number of entries in key order, beginning--- with the smallest keys.------ Returns a possibly empty map ('Map'), in case we drop all of the--- elements (which can happen if we drop a number greater than or equal to--- the number of items in the map)------ @--- drop n = Data.Map.fromDistinctAscList . Data.List.NonEmpty.drop' n . 'toList'--- @-drop ::- Int ->- NEMap k a ->- Map k a-drop 0 n = toMap n-drop i (NEMap _ _ m) = M.drop (i - 1) m-{-# INLINEABLE drop #-}---- | /O(log n)/. Split a map at a particular index @i@.------ * @'This' n1@ means that there are less than @i@ items in the map, and--- @n1@ is the original map.--- * @'That' n2@ means @i@ was 0; we dropped 0 items, so @n2@ is the--- original map.--- * @'These' n1 n2@ gives @n1@ (taking @i@ items from the original map)--- and @n2@ (dropping @i@ items from the original map))-splitAt ::- Int ->- NEMap k a ->- These (NEMap k a) (NEMap k a)-splitAt 0 n = That n-splitAt i n@(NEMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of- (Nothing, Nothing) -> This (singleton k v)- (Just _, Nothing) -> This n- (Nothing, Just n2) -> These (singleton k v) n2- (Just _, Just n2) -> These (insertMapMin k v m1) n2- where- (m1, m2) = M.splitAt (i - 1) m0-{-# INLINEABLE splitAt #-}---- | /O(1)/. The minimal key of the map. Note that this is total, making--- 'Data.Map.lookupMin' obsolete. It is constant-time, so has better--- asymptotics than @Data.Map.lookupMin@ and @Data.Map.findMin@, as well.------ > findMin (fromList ((5,"a") :| [(3,"b")])) == (3,"b")-findMin :: NEMap k a -> (k, a)-findMin (NEMap k v _) = (k, v)-{-# INLINE findMin #-}---- | /O(log n)/. The maximal key of the map. Note that this is total, making--- 'Data.Map.lookupMin' obsolete.------ > findMax (fromList ((5,"a") :| [(3,"b")])) == (5,"a")-findMax :: NEMap k a -> (k, a)-findMax (NEMap k v m) = fromMaybe (k, v) . M.lookupMax $ m-{-# INLINE findMax #-}---- | /O(1)/. Delete the minimal key. Returns a potentially empty map--- ('Map'), because we might end up deleting the final key in a singleton--- map. It is constant-time, so has better asymptotics than--- 'Data.Map.deleteMin'.------ > deleteMin (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.Map.fromList [(5,"a"), (7,"c")]--- > deleteMin (singleton 5 "a") == Data.Map.empty-deleteMin :: NEMap k a -> Map k a-deleteMin (NEMap _ _ m) = m-{-# INLINE deleteMin #-}---- | /O(log n)/. Delete the maximal key. Returns a potentially empty map--- ('Map'), because we might end up deleting the final key in a singleton--- map.------ > deleteMax (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.Map.fromList [(3,"b"), (5,"a")]--- > deleteMax (singleton 5 "a") == Data.Map.empty-deleteMax :: NEMap k a -> Map k a-deleteMax (NEMap k v m) = case M.maxView m of- Nothing -> M.empty- Just (_, m') -> insertMinMap k v m'-{-# INLINE deleteMax #-}---- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the--- minimal key. Returns a potentially empty map ('Map'), because we might--- end up deleting the final key in the map if the function returns--- 'Nothing'. See 'adjustMin' for a version that can guaruntee that we--- return a non-empty map.------ > updateMin (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "Xb"), (5, "a")]--- > updateMin (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"-updateMin :: (a -> Maybe a) -> NEMap k a -> Map k a-updateMin f = updateMinWithKey (const f)-{-# INLINE updateMin #-}---- | /O(1)/. A version of 'updateMin' that disallows deletion, allowing us--- to guarantee that the result is also non-empty.-adjustMin :: (a -> a) -> NEMap k a -> NEMap k a-adjustMin f = adjustMinWithKey (const f)-{-# INLINE adjustMin #-}---- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the--- minimal key. Returns a potentially empty map ('Map'), because we might--- end up deleting the final key in the map if the function returns--- 'Nothing'. See 'adjustMinWithKey' for a version that guaruntees--- a non-empty map.------ > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3,"3:b"), (5,"a")]--- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"-updateMinWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a-updateMinWithKey f (NEMap k v m) = maybe id (insertMinMap k) (f k v) m-{-# INLINE updateMinWithKey #-}---- | /O(1)/. A version of 'adjustMaxWithKey' that disallows deletion,--- allowing us to guarantee that the result is also non-empty. Note that--- it also is able to have better asymptotics than 'updateMinWithKey' in--- general.-adjustMinWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a-adjustMinWithKey f (NEMap k v m) = NEMap k (f k v) m-{-# INLINE adjustMinWithKey #-}---- | /O(log n)/. Update the value at the maximal key. Returns--- a potentially empty map ('Map'), because we might end up deleting the--- final key in the map if the function returns 'Nothing'. See 'adjustMax'--- for a version that can guarantee that we return a non-empty map.------ > updateMax (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "Xa")]--- > updateMax (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"-updateMax :: (a -> Maybe a) -> NEMap k a -> Map k a-updateMax f = updateMaxWithKey (const f)-{-# INLINE updateMax #-}---- | /O(log n)/. A version of 'updateMax' that disallows deletion, allowing--- us to guarantee that the result is also non-empty.-adjustMax :: (a -> a) -> NEMap k a -> NEMap k a-adjustMax f = adjustMaxWithKey (const f)-{-# INLINE adjustMax #-}---- | /O(log n)/. Update the value at the maximal key. Returns--- a potentially empty map ('Map'), because we might end up deleting the--- final key in the map if the function returns 'Nothing'. See--- 'adjustMaxWithKey' for a version that guaruntees a non-empty map.------ > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3,"3:b"), (5,"a")]--- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"-updateMaxWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a-updateMaxWithKey f (NEMap k v m)- | M.null m = maybe m (M.singleton k) $ f k v- | otherwise =- insertMinMap k v- . M.updateMaxWithKey f- $ m-{-# INLINE updateMaxWithKey #-}---- | /O(log n)/. A version of 'updateMaxWithKey' that disallows deletion,--- allowing us to guarantee that the result is also non-empty.-adjustMaxWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a-adjustMaxWithKey f (NEMap k0 v m)- | M.null m = NEMap k0 (f k0 v) m- | otherwise =- insertMapMin k0 v- . M.updateMaxWithKey (\k -> Just . f k)- $ m-{-# INLINE adjustMaxWithKey #-}---- | /O(1)/. Retrieves the value associated with minimal key of the--- map, and the map stripped of that element. It is constant-time, so has--- better asymptotics than @Data.Map.minView@ for 'Map'.------ Note that unlike @Data.Map.minView@ for 'Map', this cannot ever fail,--- so doesn't need to return in a 'Maybe'. However, the result 'Map' is--- potentially empty, since the original map might have contained just--- a single item.------ > minView (fromList ((5,"a") :| [(3,"b")])) == ("b", Data.Map.singleton 5 "a")-minView :: NEMap k a -> (a, Map k a)-minView = first snd . deleteFindMin-{-# INLINE minView #-}---- | /O(1)/. Delete and find the minimal key-value pair. It is--- constant-time, so has better asymptotics that @Data.Map.minView@ for--- 'Map'.------ Note that unlike @Data.Map.deleteFindMin@ for 'Map', this cannot ever--- fail, and so is a total function. However, the result 'Map' is--- potentially empty, since the original map might have contained just--- a single item.------ > deleteFindMin (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((3,"b"), Data.Map.fromList [(5,"a"), (10,"c")])-deleteFindMin :: NEMap k a -> ((k, a), Map k a)-deleteFindMin (NEMap k v m) = ((k, v), m)-{-# INLINE deleteFindMin #-}---- | /O(log n)/. Retrieves the value associated with maximal key of the--- map, and the map stripped of that element.------ Note that unlike @Data.Map.maxView@ from 'Map', this cannot ever fail,--- so doesn't need to return in a 'Maybe'. However, the result 'Map' is--- potentially empty, since the original map might have contained just--- a single item.------ > maxView (fromList ((5,"a") :| [(3,"b")])) == ("a", Data.Map.singleton 3 "b")-maxView :: NEMap k a -> (a, Map k a)-maxView = first snd . deleteFindMax-{-# INLINE maxView #-}---- | /O(log n)/. Delete and find the minimal key-value pair.------ Note that unlike @Data.Map.deleteFindMax@ for 'Map', this cannot ever--- fail, and so is a total function. However, the result 'Map' is--- potentially empty, since the original map might have contained just--- a single item.------ > deleteFindMax (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((10,"c"), Data.Map.fromList [(3,"b"), (5,"a")])-deleteFindMax :: NEMap k a -> ((k, a), Map k a)-deleteFindMax (NEMap k v m) =- maybe ((k, v), M.empty) (second (insertMinMap k v))- . M.maxViewWithKey- $ m-{-# INLINE deleteFindMax #-}---- | Special property of non-empty maps: The type of non-empty maps over--- uninhabited keys is itself uninhabited.------ This property also exists for /values/ inside a non-empty container--- (like for 'NESet', 'NESeq', and 'NEIntMap'); this can be witnessed using--- the function @'absurd' . 'fold1'@.------ @since 0.3.1.0-absurdNEMap :: NEMap Void a -> b-absurdNEMap = \case {}---- ------------------------------ Combining functions--- --------------------------------- Code comes from "Data.Map.Internal" from containers, modified slightly--- to work with NonEmpty------ Copyright : (c) Daan Leijen 2002--- (c) Andriy Palamarchuk 2008--combineEq :: Eq a => NonEmpty (a, b) -> NonEmpty (a, b)-combineEq = \case- x :| [] -> x :| []- x :| xx@(_ : _) -> go x xx- where- go z [] = z :| []- go z@(kz, _) (x@(kx, xx) : xs')- | kx == kz = go (kx, xx) xs'- | otherwise = z NE.<| go x xs'--combineEqWith ::- Eq a =>- (a -> b -> b -> b) ->- NonEmpty (a, b) ->- NonEmpty (a, b)-combineEqWith f = \case- x :| [] -> x :| []- x :| xx@(_ : _) -> go x xx- where- go z [] = z :| []- go z@(kz, zz) (x@(kx, xx) : xs')- | kx == kz = let yy = f kx xx zz in go (kx, yy) xs'- | otherwise = z NE.<| go x xs'+-- |+-- Module : Data.Map.NonEmpty+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- = Non-Empty Finite Maps+--+-- This module re-exports "Data.Map.NonEmpty.Lazy". Import+-- "Data.Map.NonEmpty.Strict" for the strict value interface.+module Data.Map.NonEmpty (+ module Data.Map.NonEmpty.Lazy,+) where++import Data.Map.NonEmpty.Lazy
src/Data/Map/NonEmpty/Internal.hs view
@@ -1,11 +1,3 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ViewPatterns #-} {-# OPTIONS_HADDOCK not-home #-} -- |@@ -17,710 +9,10 @@ -- Stability : experimental -- Portability : non-portable ----- Unsafe internal-use functions used in the implementation of--- "Data.Map.NonEmpty". These functions can potentially be used to break--- the abstraction of 'NEMap' and produce unsound maps, so be wary!+-- Internal compatibility module for the lazy non-empty map implementation.+-- Import "Data.Map.NonEmpty.Strict.Internal" for the strict value variant. module Data.Map.NonEmpty.Internal (- -- * Non-Empty Map type- NEMap (..),- singleton,- nonEmptyMap,- withNonEmpty,- fromList,- toList,- map,- insertWith,- union,- unions,- elems,- size,- toMap,-- -- * Folds- foldr,- foldr',- foldr1,- foldl,- foldl',- foldl1,-- -- * Traversals- traverseWithKey,- traverseWithKey1,- foldMapWithKey,-- -- * Unsafe Map Functions- insertMinMap,- insertMaxMap,-- -- * Debug- valid,+ module Data.Map.NonEmpty.Lazy.Internal, ) where -import Control.Applicative-import Control.Comonad-import Control.DeepSeq-import Control.Monad-import qualified Data.Aeson as A-import Data.Coerce-import Data.Data-import qualified Data.Foldable as F-import Data.Foldable.WithIndex (FoldableWithIndex (..))-import Data.Function-import Data.Functor.Alt-import Data.Functor.Classes-import Data.Functor.Invariant-import Data.Functor.WithIndex (FunctorWithIndex (..))-import Data.List.NonEmpty (NonEmpty (..))-import qualified Data.Map as M-import Data.Map.Internal (Map (..))-import qualified Data.Map.Internal as M-import Data.Maybe-import Data.Semigroup-import Data.Semigroup.Foldable (Foldable1 (fold1))-import qualified Data.Semigroup.Foldable as F1-import Data.Semigroup.Traversable (Traversable1 (..))-import Data.Traversable.WithIndex (TraversableWithIndex (..))-import qualified GHC.Exts as Exts-import Text.Read-import Prelude hiding (Foldable (..), map)---- | A non-empty (by construction) map from keys @k@ to values @a@. At--- least one key-value pair exists in an @'NEMap' k v@ at all times.------ Functions that /take/ an 'NEMap' can safely operate on it with the--- assumption that it has at least one key-value pair.------ Functions that /return/ an 'NEMap' provide an assurance that the result--- has at least one key-value pair.------ "Data.Map.NonEmpty" re-exports the API of "Data.Map", faithfully--- reproducing asymptotics, typeclass constraints, and semantics.--- Functions that ensure that input and output maps are both non-empty--- (like 'Data.Map.NonEmpty.insert') return 'NEMap', but functions that--- might potentially return an empty map (like 'Data.Map.NonEmpty.delete')--- return a 'Map' instead.------ You can directly construct an 'NEMap' with the API from--- "Data.Map.NonEmpty"; it's more or less the same as constructing a normal--- 'Map', except you don't have access to 'Data.Map.empty'. There are also--- a few ways to construct an 'NEMap' from a 'Map':------ 1. The 'nonEmptyMap' smart constructor will convert a @'Map' k a@ into--- a @'Maybe' ('NEMap' k a)@, returning 'Nothing' if the original 'Map'--- was empty.--- 2. You can use the 'Data.Map.NonEmpty.insertMap' family of functions to--- insert a value into a 'Map' to create a guaranteed 'NEMap'.--- 3. You can use the 'Data.Map.NonEmpty.IsNonEmpty' and--- 'Data.Map.NonEmpty.IsEmpty' patterns to "pattern match" on a 'Map'--- to reveal it as either containing a 'NEMap' or an empty map.--- 4. 'withNonEmpty' offers a continuation-based interface for--- deconstructing a 'Map' and treating it as if it were an 'NEMap'.------ You can convert an 'NEMap' into a 'Map' with 'toMap' or--- 'Data.Map.NonEmpty.IsNonEmpty', essentially "obscuring" the non-empty--- property from the type.-data NEMap k a- = NEMap- { nemK0 :: !k- -- ^ invariant: must be smaller than smallest key in map- , nemV0 :: a- , nemMap :: !(Map k a)- }- deriving (Typeable)--instance (Eq k, Eq a) => Eq (NEMap k a) where- t1 == t2 =- M.size (nemMap t1) == M.size (nemMap t2)- && toList t1 == toList t2--instance (Ord k, Ord a) => Ord (NEMap k a) where- compare = compare `on` toList- (<) = (<) `on` toList- (>) = (>) `on` toList- (<=) = (<=) `on` toList- (>=) = (>=) `on` toList--instance Eq2 NEMap where- liftEq2 eqk eqv m n =- size m == size n && liftEq (liftEq2 eqk eqv) (toList m) (toList n)--instance Eq k => Eq1 (NEMap k) where- liftEq = liftEq2 (==)--instance Ord2 NEMap where- liftCompare2 cmpk cmpv m n =- liftCompare (liftCompare2 cmpk cmpv) (toList m) (toList n)--instance Ord k => Ord1 (NEMap k) where- liftCompare = liftCompare2 compare--instance Show2 NEMap where- liftShowsPrec2 spk slk spv slv d m =- showsUnaryWith (liftShowsPrec sp sl) "fromList" d (toList m)- where- sp = liftShowsPrec2 spk slk spv slv- sl = liftShowList2 spk slk spv slv--instance Show k => Show1 (NEMap k) where- liftShowsPrec = liftShowsPrec2 showsPrec showList--instance (Ord k, Read k) => Read1 (NEMap k) where- liftReadsPrec rp rl =- readsData $- readsUnaryWith (liftReadsPrec rp' rl') "fromList" fromList- where- rp' = liftReadsPrec rp rl- rl' = liftReadList rp rl--instance (Ord k, Read k, Read e) => Read (NEMap k e) where- readPrec = parens $ prec 10 $ do- Ident "fromList" <- lexP- xs <- parens . prec 10 $ readPrec- return (fromList xs)- readListPrec = readListPrecDefault--instance (Show k, Show a) => Show (NEMap k a) where- showsPrec d m =- showParen (d > 10) $- showString "fromList (" . shows (toList m) . showString ")"--instance (NFData k, NFData a) => NFData (NEMap k a) where- rnf (NEMap k v a) = rnf k `seq` rnf v `seq` rnf a---- | @since 0.3.6.0-instance FunctorWithIndex k (NEMap k) where- imap f (NEMap k v m) = NEMap k (f k v) (M.mapWithKey f m)---- | @since 0.3.6.0-instance FoldableWithIndex k (NEMap k) where- ifoldMap = foldMapWithKey---- | @since 0.3.6.0-instance TraversableWithIndex k (NEMap k) where- itraverse f (NEMap k v m) = NEMap k <$> f k v <*> M.traverseWithKey f m---- | @since 0.3.6.0-instance Ord k => Exts.IsList (NEMap k a) where- type Item (NEMap k a) = (k, a)-- fromList (a : as) = fromList (a :| as)- fromList [] = errorWithoutStackTrace "Data.Map.NonEmpty.fromList: empty list"-- toList = F.toList . toList---- Data instance code from Data.Map.Internal------ Copyright : (c) Daan Leijen 2002--- (c) Andriy Palamarchuk 2008-#if MIN_VERSION_base(4,16,0)-instance (Data k, Data a, Ord k) => Data (NEMap k a) where- gfoldl f z m = z fromList `f` toList m- toConstr _ = fromListConstr- gunfold k z c = case constrIndex c of- 1 -> k (z fromList)- _ -> error "gunfold"- dataTypeOf _ = mapDataType- dataCast2 = gcast2-#else-#ifndef __HLINT__-instance (Data k, Data a, Ord k) => Data (NEMap k a) where- gfoldl f z m = z fromList `f` toList m- toConstr _ = fromListConstr- gunfold k z c = case constrIndex c of- 1 -> k (z fromList)- _ -> error "gunfold"- dataTypeOf _ = mapDataType- dataCast2 f = gcast2 f-#endif-#endif--fromListConstr :: Constr-fromListConstr = mkConstr mapDataType "fromList" [] Prefix--mapDataType :: DataType-mapDataType = mkDataType "Data.Map.NonEmpty.NonEmpty.Internal.NEMap" [fromListConstr]--instance (A.ToJSONKey k, A.ToJSON a) => A.ToJSON (NEMap k a) where- toJSON = A.toJSON . toMap- toEncoding = A.toEncoding . toMap--instance (A.FromJSONKey k, Ord k, A.FromJSON a) => A.FromJSON (NEMap k a) where- parseJSON =- withNonEmpty (fail err) pure- <=< A.parseJSON- where- err = "NEMap: Non-empty map expected, but empty map found"---- | @since 0.3.4.4-instance Ord k => Alt (NEMap k) where- (<!>) = union- {-# INLINE (<!>) #-}---- | /O(n)/. Fold the values in the map using the given right-associative--- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'elems'@.------ > elemsList map = foldr (:) [] map------ > let f a len = len + (length a)--- > foldr f 0 (fromList ((5,"a") :| [(3,"bbb")])) == 4-foldr :: (a -> b -> b) -> b -> NEMap k a -> b-foldr f z (NEMap _ v m) = v `f` M.foldr f z m-{-# INLINE foldr #-}---- | /O(n)/. A strict version of 'foldr'. Each application of the operator--- is evaluated before using the result in the next application. This--- function is strict in the starting value.-foldr' :: (a -> b -> b) -> b -> NEMap k a -> b-foldr' f z (NEMap _ v m) = v `f` y- where- !y = M.foldr' f z m-{-# INLINE foldr' #-}---- | /O(n)/. A version of 'foldr' that uses the value at the maximal key in--- the map as the starting value.------ Note that, unlike 'Data.Foldable.foldr1' for 'Map', this function is--- total if the input function is total.-foldr1 :: (a -> a -> a) -> NEMap k a -> a-foldr1 f (NEMap _ v m) =- maybe v (f v . uncurry (M.foldr f))- . M.maxView- $ m-{-# INLINE foldr1 #-}---- | /O(n)/. Fold the values in the map using the given left-associative--- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'elems'@.------ > elemsList = reverse . foldl (flip (:)) []------ > let f len a = len + (length a)--- > foldl f 0 (fromList ((5,"a") :| [(3,"bbb")])) == 4-foldl :: (a -> b -> a) -> a -> NEMap k b -> a-foldl f z (NEMap _ v m) = M.foldl f (f z v) m-{-# INLINE foldl #-}---- | /O(n)/. A strict version of 'foldl'. Each application of the operator--- is evaluated before using the result in the next application. This--- function is strict in the starting value.-foldl' :: (a -> b -> a) -> a -> NEMap k b -> a-foldl' f z (NEMap _ v m) = M.foldl' f x m- where- !x = f z v-{-# INLINE foldl' #-}---- | /O(n)/. A version of 'foldl' that uses the value at the minimal key in--- the map as the starting value.------ Note that, unlike 'Data.Foldable.foldl1' for 'Map', this function is--- total if the input function is total.-foldl1 :: (a -> a -> a) -> NEMap k a -> a-foldl1 f (NEMap _ v m) = M.foldl f v m-{-# INLINE foldl1 #-}---- | /O(n)/. Fold the keys and values in the map using the given semigroup,--- such that------ @'foldMapWithKey' f = 'Data.Semigroup.Foldable.fold1' . 'Data.Map.NonEmpty.mapWithKey' f@------ This can be an asymptotically faster than--- 'Data.Map.NonEmpty.foldrWithKey' or 'Data.Map.NonEmpty.foldlWithKey' for--- some monoids.---- TODO: benchmark against maxView method-foldMapWithKey ::- Semigroup m =>- (k -> a -> m) ->- NEMap k a ->- m-#if MIN_VERSION_base(4,11,0)-foldMapWithKey f (NEMap k0 v m) = maybe (f k0 v) (f k0 v <>)- . M.foldMapWithKey (\k -> Just . f k)- $ m-#else-foldMapWithKey f (NEMap k0 v m) = option (f k0 v) (f k0 v <>)- . M.foldMapWithKey (\k -> Option . Just . f k)- $ m-#endif-{-# INLINE foldMapWithKey #-}---- | /O(n)/. Map a function over all values in the map.------ > map (++ "x") (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "bx") :| [(5, "ax")])-map :: (a -> b) -> NEMap k a -> NEMap k b-map f (NEMap k0 v m) = NEMap k0 (f v) (M.map f m)-{-# NOINLINE [1] map #-}--{-# RULES-"map/map" forall f g xs. map f (map g xs) = map (f . g) xs- #-}-{-# RULES-"map/coerce" map coerce = coerce- #-}---- | /O(m*log(n\/m + 1)), m <= n/.--- 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' == 'Data.Map.NonEmpty.unionWith' 'const'@).------ > union (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "a"), (7, "C")])-union ::- Ord k =>- NEMap k a ->- NEMap k a ->- NEMap k a-union n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of- LT -> NEMap k1 v1 . M.union m1 . toMap $ n2- EQ -> NEMap k1 v1 . M.union m1 $ m2- GT -> NEMap k2 v2 . M.union (toMap n1) $ m2-{-# INLINE union #-}---- | The left-biased union of a non-empty list of maps.------ > unions (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])--- > == fromList [(3, "b"), (5, "a"), (7, "C")]--- > unions (fromList ((5, "A3") :| [(3, "B3")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "a") :| [(3, "b")])])--- > == fromList ((3, "B3") :| [(5, "A3"), (7, "C")])-unions ::- (Foldable1 f, Ord k) =>- f (NEMap k a) ->- NEMap k a-unions (F1.toNonEmpty -> (m :| ms)) = F.foldl' union m ms-{-# INLINE unions #-}---- | /O(n)/.--- Return all elements of the map in the ascending order of their keys.------ > elems (fromList ((5,"a") :| [(3,"b")])) == ("b" :| ["a"])-elems :: NEMap k a -> NonEmpty a-elems (NEMap _ v m) = v :| M.elems m-{-# INLINE elems #-}---- | /O(1)/. The number of elements in the map. Guaranteed to be greater--- than zero.------ > size (singleton 1 'a') == 1--- > size (fromList ((1,'a') :| [(2,'c'), (3,'b')])) == 3-size :: NEMap k a -> Int-size (NEMap _ _ m) = 1 + M.size m-{-# INLINE size #-}---- | /O(log n)/.--- Convert a non-empty map back into a normal possibly-empty map, for usage--- with functions that expect 'Map'.------ Can be thought of as "obscuring" the non-emptiness of the map in its--- type. See the 'Data.Map.NonEmpty.IsNotEmpty' pattern.------ 'nonEmptyMap' and @'maybe' 'Data.Map.empty' 'toMap'@ form an isomorphism: they--- are perfect structure-preserving inverses of eachother.------ > toMap (fromList ((3,"a") :| [(5,"b")])) == Data.Map.fromList [(3,"a"), (5,"b")]-toMap :: NEMap k a -> Map k a-toMap (NEMap k v m) = insertMinMap k v m-{-# INLINE toMap #-}---- | /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.------ /Use 'traverseWithKey1'/ whenever possible (if your 'Applicative'--- also has 'Apply' instance). This version is provided only for types--- that do not have 'Apply' instance, since 'Apply' is not at the moment--- (and might not ever be) an official superclass of 'Applicative'.------ @--- 'traverseWithKey' f = 'unwrapApplicative' . 'traverseWithKey1' (\\k -> WrapApplicative . f k)--- @-traverseWithKey ::- Applicative t =>- (k -> a -> t b) ->- NEMap k a ->- t (NEMap k b)-traverseWithKey f (NEMap k v m0) = NEMap k <$> f k v <*> M.traverseWithKey f m0-{-# INLINE traverseWithKey #-}---- | /O(n)/.--- @'traverseWithKey1' f m == 'fromList' <$> 'traverse1' (\(k, v) -> (,) k <$> f k v) ('toList' m)@------ That is, behaves exactly like a regular 'traverse1' except that the traversing--- function also has access to the key associated with a value.------ Is more general than 'traverseWithKey', since works with all 'Apply',--- and not just 'Applicative'.---- TODO: benchmark against maxView-based methods-traverseWithKey1 ::- Apply t =>- (k -> a -> t b) ->- NEMap k a ->- t (NEMap k b)-traverseWithKey1 f (NEMap k0 v m0) = case runMaybeApply m1 of- Left m2 -> NEMap k0 <$> f k0 v <.> m2- Right m2 -> flip (NEMap k0) m2 <$> f k0 v- where- m1 = M.traverseWithKey (\k -> MaybeApply . Left . f k) m0-{-# INLINEABLE traverseWithKey1 #-}---- | /O(n)/. Convert the map to a non-empty list of key\/value pairs.------ > toList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])-toList :: NEMap k a -> NonEmpty (k, a)-toList (NEMap k v m) = (k, v) :| M.toList m-{-# INLINE toList #-}---- | /O(log n)/. Smart constructor for an 'NEMap' from a 'Map'. Returns--- 'Nothing' if the 'Map' was originally actually empty, and @'Just' n@--- with an 'NEMap', if the 'Map' was not empty.------ 'nonEmptyMap' and @'maybe' 'Data.Map.empty' 'toMap'@ form an--- isomorphism: they are perfect structure-preserving inverses of--- eachother.------ See 'Data.Map.NonEmpty.IsNonEmpty' for a pattern synonym that lets you--- "match on" the possiblity of a 'Map' being an 'NEMap'.------ > nonEmptyMap (Data.Map.fromList [(3,"a"), (5,"b")]) == Just (fromList ((3,"a") :| [(5,"b")]))-nonEmptyMap :: Map k a -> Maybe (NEMap k a)-nonEmptyMap = (fmap . uncurry . uncurry) NEMap . M.minViewWithKey-{-# INLINE nonEmptyMap #-}---- | /O(log n)/. A general continuation-based way to consume a 'Map' as if--- it were an 'NEMap'. @'withNonEmpty' def f@ will take a 'Map'. If map is--- empty, it will evaluate to @def@. Otherwise, a non-empty map 'NEMap'--- will be fed to the function @f@ instead.------ @'nonEmptyMap' == 'withNonEmpty' 'Nothing' 'Just'@-withNonEmpty ::- -- | value to return if map is empty- r ->- -- | function to apply if map is not empty- (NEMap k a -> r) ->- Map k a ->- r-withNonEmpty def f = maybe def f . nonEmptyMap-{-# INLINE withNonEmpty #-}---- | /O(n*log n)/. Build a non-empty map from a non-empty list of--- key\/value pairs. See also 'Data.Map.NonEmpty.fromAscList'. If the list--- contains more than one value for the same key, the last value for the--- key is retained.------ > fromList ((5,"a") :| [(3,"b"), (5, "c")]) == fromList ((5,"c") :| [(3,"b")])--- > fromList ((5,"c") :| [(3,"b"), (5, "a")]) == fromList ((5,"a") :| [(3,"b")])---- TODO: write manually and optimize to be equivalent to--- 'fromDistinctAscList' if items are ordered, just like the actual--- 'M.fromList'.-fromList :: Ord k => NonEmpty (k, a) -> NEMap k a-fromList ((k, v) :| xs) =- withNonEmpty (singleton k v) (insertWith (const id) k v)- . M.fromList- $ xs-{-# INLINE fromList #-}---- | /O(1)/. A map with a single element.------ > singleton 1 'a' == fromList ((1, 'a') :| [])--- > size (singleton 1 'a') == 1-singleton :: k -> a -> NEMap k a-singleton k v = NEMap k v M.empty-{-# INLINE singleton #-}---- | /O(log n)/. Insert with a function, combining new value and old value.--- @'insertWith' f key value mp@ will insert the pair (key, value) into--- @mp@ if key does not exist in the map. If the key does exist, the--- function will insert the pair @(key, f new_value old_value)@.------ See 'Data.Map.NonEmpty.insertMapWith' for a version where the first--- argument is a 'Map'.------ > insertWith (++) 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "xxxa")])--- > insertWith (++) 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])-insertWith ::- Ord k =>- (a -> a -> a) ->- k ->- a ->- NEMap k a ->- NEMap k a-insertWith f k v n@(NEMap k0 v0 m) = case compare k k0 of- LT -> NEMap k v . toMap $ n- EQ -> NEMap k (f v v0) m- GT -> NEMap k0 v0 $ M.insertWith f k v m-{-# INLINE insertWith #-}---- | Left-biased union-instance Ord k => Semigroup (NEMap k a) where- (<>) = union- {-# INLINE (<>) #-}- sconcat = unions- {-# INLINE sconcat #-}--instance Functor (NEMap k) where- fmap = map- {-# INLINE fmap #-}- x <$ NEMap k _ m = NEMap k x (x <$ m)- {-# INLINE (<$) #-}---- | @since 0.3.4.4-instance Invariant (NEMap k) where- invmap f _ = fmap f- {-# INLINE invmap #-}---- | Traverses elements in order of ascending keys------ 'Data.Foldable.foldr1', 'Data.Foldable.foldl1', 'Data.Foldable.minimum',--- 'Data.Foldable.maximum' are all total.-#if MIN_VERSION_base(4,11,0)-instance F.Foldable (NEMap k) where- fold (NEMap _ v m) = v <> F.fold m- {-# INLINE fold #-}- foldMap f (NEMap _ v m) = f v <> F.foldMap f m- {-# INLINE foldMap #-}- foldr = foldr- {-# INLINE foldr #-}- foldr' = foldr'- {-# INLINE foldr' #-}- foldr1 = foldr1- {-# INLINE foldr1 #-}- foldl = foldl- {-# INLINE foldl #-}- foldl' = foldl'- {-# INLINE foldl' #-}- foldl1 = foldl1- {-# INLINE foldl1 #-}- null _ = False- {-# INLINE null #-}- length = size- {-# INLINE length #-}- elem x (NEMap _ v m) = F.elem x m- || x == v- {-# INLINE elem #-}- -- TODO: use build- toList = F.toList . elems- {-# INLINE toList #-}-#else-instance F.Foldable (NEMap k) where- fold (NEMap _ v m) = v `mappend` F.fold m- {-# INLINE fold #-}- foldMap f (NEMap _ v m) = f v `mappend` F.foldMap f m- {-# INLINE foldMap #-}- foldr = foldr- {-# INLINE foldr #-}- foldr' = foldr'- {-# INLINE foldr' #-}- foldr1 = foldr1- {-# INLINE foldr1 #-}- foldl = foldl- {-# INLINE foldl #-}- foldl' = foldl'- {-# INLINE foldl' #-}- foldl1 = foldl1- {-# INLINE foldl1 #-}- null _ = False- {-# INLINE null #-}- length = size- {-# INLINE length #-}- elem x (NEMap _ v m) = F.elem x m- || x == v- {-# INLINE elem #-}- -- TODO: use build- toList = F.toList . elems- {-# INLINE toList #-}-#endif---- | Traverses elements in order of ascending keys-instance Traversable (NEMap k) where- traverse f (NEMap k v m) = NEMap k <$> f v <*> traverse f m- {-# INLINE traverse #-}- sequenceA (NEMap k v m) = NEMap k <$> v <*> sequenceA m- {-# INLINE sequenceA #-}---- | Traverses elements in order of ascending keys-#if MIN_VERSION_base(4,11,0)-instance Foldable1 (NEMap k) where- fold1 (NEMap _ v m) = maybe v (v <>)- . F.foldMap Just- $ m- {-# INLINE fold1 #-}- foldMap1 f = foldMapWithKey (const f)- {-# INLINE foldMap1 #-}- toNonEmpty = elems- {-# INLINE toNonEmpty #-}-#else-instance Foldable1 (NEMap k) where- fold1 (NEMap _ v m) = option v (v <>)- . F.foldMap (Option . Just)- $ m- {-# INLINE fold1 #-}- foldMap1 f = foldMapWithKey (const f)- {-# INLINE foldMap1 #-}- toNonEmpty = elems- {-# INLINE toNonEmpty #-}-#endif---- | Traverses elements in order of ascending keys-instance Traversable1 (NEMap k) where- traverse1 f = traverseWithKey1 (const f)- {-# INLINE traverse1 #-}- sequence1 (NEMap k v m0) = case runMaybeApply m1 of- Left m2 -> NEMap k <$> v <.> m2- Right m2 -> flip (NEMap k) m2 <$> v- where- m1 = traverse (MaybeApply . Left) m0- {-# INLINEABLE sequence1 #-}---- | 'extract' gets the value at the minimal key, and 'duplicate' produces--- a map of maps comprised of all keys from the original map greater than--- or equal to the current key.------ @since 0.1.1.0-instance Comonad (NEMap k) where- extract = nemV0- {-# INLINE extract #-}- duplicate n0@(NEMap k0 _ m0) =- NEMap k0 n0- . snd- . M.mapAccumWithKey go m0- $ m0- where- go m k v = (m', NEMap k v m')- where- !m' = M.deleteMin m- {-# INLINE duplicate #-}---- | /O(n)/. Test if the internal map structure is valid.-valid :: Ord k => NEMap k a -> Bool-valid (NEMap k _ m) =- M.valid m- && all ((k <) . fst . fst) (M.minViewWithKey m)---- | /O(log n)/. Insert new key and value into a map where keys are--- /strictly greater than/ the new key. That is, the new key must be--- /strictly less than/ all keys present in the 'Map'. /The precondition--- is not checked./------ While this has the same asymptotics as @Data.Map.insert@, it saves--- a constant factor for key comparison (so may be helpful if comparison is--- expensive) and also does not require an 'Ord' instance for the key type.-insertMinMap :: k -> a -> Map k a -> Map k a-insertMinMap kx x = \case- Tip -> M.singleton kx x- Bin _ ky y l r -> M.balanceL ky y (insertMinMap kx x l) r-{-# INLINEABLE insertMinMap #-}---- | /O(log n)/. Insert new key and value into a map where keys are--- /strictly less than/ the new key. That is, the new key must be--- /strictly greater than/ all keys present in the 'Map'. /The--- precondition is not checked./------ While this has the same asymptotics as @Data.Map.insert@, it saves--- a constant factor for key comparison (so may be helpful if comparison is--- expensive) and also does not require an 'Ord' instance for the key type.-insertMaxMap :: k -> a -> Map k a -> Map k a-insertMaxMap kx x = \case- Tip -> M.singleton kx x- Bin _ ky y l r -> M.balanceR ky y l (insertMaxMap kx x r)-{-# INLINEABLE insertMaxMap #-}+import Data.Map.NonEmpty.Lazy.Internal
+ src/Data/Map/NonEmpty/Lazy.hs view
@@ -0,0 +1,2492 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE EmptyCase #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ViewPatterns #-}++-- |+-- Module : Data.Map.NonEmpty.Lazy+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- = Non-Empty Finite Maps (lazy interface)+--+-- The @'NEMap' k v@ type represents a non-empty finite map (sometimes+-- called a dictionary) from keys of type @k@ to values of type @v@.+-- An 'NEMap' is strict in its keys but lazy in its values.+--+-- See documentation for 'NEMap' for information on how to convert and+-- manipulate such non-empty maps.+--+-- This module essentially re-imports the API of "Data.Map.Lazy" and its+-- 'Map' type, along with semantics and asymptotics. In most situations,+-- asymptotics are different only by a constant factor. In some+-- situations, asmyptotics are even better (constant-time instead of+-- log-time). All typeclass constraints are identical to their "Data.Map"+-- counterparts.+--+-- Because 'NEMap' is implemented using 'Map', all of the caveats of using+-- 'Map' apply (such as the limitation of the maximum size of maps).+--+-- All functions take non-empty maps as inputs. In situations where their+-- results can be guarunteed to also be non-empty, they also return+-- non-empty maps. In situations where their results could potentially be+-- empty, 'Map' is returned instead.+--+-- Some variants of functions (like 'alter'', 'alterF'', 'adjustAt',+-- 'adjustMin', 'adjustMax', 'adjustMinWithKey', 'adjustMaxWithKey') are+-- provided in a way restructured to preserve guaruntees of non-empty maps+-- being returned.+--+-- Some functions (like 'mapEither', 'partition', 'spanAntitone', 'split')+-- have modified return types to account for possible configurations of+-- non-emptiness.+--+-- This module is intended to be imported qualified, to avoid name clashes with+-- "Prelude" and "Data.Map" functions:+--+-- > import qualified Data.Map.NonEmpty.Lazy as NEM+--+-- Import "Data.Map.NonEmpty.Strict" for a variant strict on values.+module Data.Map.NonEmpty.Lazy (+ -- * Non-Empty Map type+ NEMap,++ -- ** Conversions between empty and non-empty maps+ pattern IsNonEmpty,+ pattern IsEmpty,+ nonEmptyMap,+ toMap,+ withNonEmpty,+ insertMap,+ insertMapWith,+ insertMapWithKey,+ insertMapMin,+ insertMapMax,+ unsafeFromMap,++ -- * Construction+ singleton,+ fromSet,++ -- ** From Unordered Lists+ fromList,+ fromListWith,+ fromListWithKey,++ -- ** From Ascending Lists+ fromAscList,+ fromAscListWith,+ fromAscListWithKey,+ fromDistinctAscList,++ -- ** From Descending Lists+ fromDescList,+ fromDescListWith,+ fromDescListWithKey,+ fromDistinctDescList,++ -- * Insertion+ insert,+ insertWith,+ insertWithKey,+ insertLookupWithKey,++ -- * Deletion\/Update+ delete,+ deleteMaybe,+ adjust,+ adjustWithKey,+ update,+ updateWithKey,+ updateLookupWithKey,+ alter,+ alterF,+ alter',+ alterF',++ -- * Query++ -- ** Lookup+ lookup,+ (!?),+ (!),+ findWithDefault,+ member,+ notMember,+ lookupLT,+ lookupGT,+ lookupLE,+ lookupGE,+ absurdNEMap,++ -- ** Size+ size,++ -- * Combine++ -- ** Union+ union,+ unionMapLeft,+ unionMapRight,+ unionWith,+ unionMapWithLeft,+ unionMapWithRight,+ unionWithKey,+ unionMapWithKeyLeft,+ unionMapWithKeyRight,+ unions,+ unionsWith,++ -- ** Difference+ difference,+ (\\),+ differenceWith,+ differenceWithKey,++ -- ** Intersection+ intersection,+ intersectionWith,+ intersectionWithKey,+ -- -- ** Unsafe general combining function+ -- , mergeWithKey++ -- * Traversal++ -- ** Map+ map,+ mapWithKey,+ traverseWithKey1,+ traverseWithKey,+ traverseMaybeWithKey1,+ traverseMaybeWithKey,+ mapAccum,+ mapAccumWithKey,+ mapAccumRWithKey,+ mapKeys,+ mapKeysWith,+ mapKeysMonotonic,++ -- * Folds+ foldr,+ foldl,+ foldr1,+ foldl1,+ foldrWithKey,+ foldlWithKey,+ foldMapWithKey,++ -- ** Strict folds+ foldr',+ foldr1',+ foldl',+ foldl1',+ foldrWithKey',+ foldlWithKey',++ -- * Conversion+ elems,+ keys,+ assocs,+ keysSet,++ -- ** Lists+ toList,++ -- ** Ordered lists+ toAscList,+ toDescList,++ -- * Filter+ filter,+ filterWithKey,+ restrictKeys,+ withoutKeys,+ partition,+ partitionWithKey,+ takeWhileAntitone,+ dropWhileAntitone,+ spanAntitone,+ mapMaybe,+ mapMaybeWithKey,+ mapEither,+ mapEitherWithKey,+ split,+ splitLookup,+ splitRoot,++ -- * Submap+ isSubmapOf,+ isSubmapOfBy,+ isProperSubmapOf,+ isProperSubmapOfBy,++ -- * Indexed+ lookupIndex,+ findIndex,+ elemAt,+ updateAt,+ adjustAt,+ deleteAt,+ take,+ drop,+ splitAt,++ -- * Min\/Max+ findMin,+ findMax,+ deleteMin,+ deleteMax,+ deleteFindMin,+ deleteFindMax,+ updateMin,+ updateMax,+ adjustMin,+ adjustMax,+ updateMinWithKey,+ updateMaxWithKey,+ adjustMinWithKey,+ adjustMaxWithKey,+ minView,+ maxView,++ -- * Debugging+ valid,+) where++import Control.Applicative+import Data.Bifunctor+import qualified Data.Foldable as F+import Data.Function+import Data.Functor.Apply+import Data.Functor.Identity+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE+import Data.Map (Map)+import qualified Data.Map as M+import Data.Map.NonEmpty.Lazy.Internal+import Data.Maybe hiding (mapMaybe)+import qualified Data.Maybe as Maybe+import Data.Semigroup.Foldable (Foldable1)+import qualified Data.Semigroup.Foldable as F1+import Data.Set (Set)+import qualified Data.Set as S+import Data.Set.NonEmpty.Internal (NESet (..))+import Data.These+import Data.Void+import Prelude hiding (Foldable (..), drop, filter, lookup, map, splitAt, take)++-- | /O(1)/ match, /O(log n)/ usage of contents. The 'IsNonEmpty' and+-- 'IsEmpty' patterns allow you to treat a 'Map' as if it were either+-- a @'IsNonEmpty' n@ (where @n@ is a 'NEMap') or an 'IsEmpty'.+--+-- For example, you can pattern match on a 'Map':+--+-- @+-- myFunc :: 'Map' K X -> Y+-- myFunc ('IsNonEmpty' n) = -- here, the user provided a non-empty map, and @n@ is the 'NEMap'+-- myFunc 'IsEmpty' = -- here, the user provided an empty map.+-- @+--+-- Matching on @'IsNonEmpty' n@ means that the original 'Map' was /not/+-- empty, and you have a verified-non-empty 'NEMap' @n@ to use.+--+-- Note that patching on this pattern is /O(1)/. However, using the+-- contents requires a /O(log n)/ cost that is deferred until after the+-- pattern is matched on (and is not incurred at all if the contents are+-- never used).+--+-- A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides+-- complete coverage.+--+-- This is a bidirectional pattern, so you can use 'IsNonEmpty' to convert+-- a 'NEMap' back into a 'Map', obscuring its non-emptiness (see 'toMap').+pattern IsNonEmpty :: NEMap k a -> Map k a+pattern IsNonEmpty n <- (nonEmptyMap -> Just n)+ where+ IsNonEmpty n = toMap n++-- | /O(1)/. The 'IsNonEmpty' and 'IsEmpty' patterns allow you to treat+-- a 'Map' as if it were either a @'IsNonEmpty' n@ (where @n@ is+-- a 'NEMap') or an 'IsEmpty'.+--+-- Matching on 'IsEmpty' means that the original 'Map' was empty.+--+-- A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides+-- complete coverage.+--+-- This is a bidirectional pattern, so you can use 'IsEmpty' as an+-- expression, and it will be interpreted as 'Data.Map.empty'.+--+-- See 'IsNonEmpty' for more information.+pattern IsEmpty :: Map k a+pattern IsEmpty <- (M.null -> True)+ where+ IsEmpty = M.empty++{-# COMPLETE IsNonEmpty, IsEmpty #-}++-- | /O(log n)/. Unsafe version of 'nonEmptyMap'. Coerces a 'Map' into an+-- 'NEMap', but is undefined (throws a runtime exception when evaluation is+-- attempted) for an empty 'Map'.+unsafeFromMap ::+ Map k a ->+ NEMap k a+unsafeFromMap = withNonEmpty e id+ where+ e = errorWithoutStackTrace "NEMap.unsafeFromMap: empty map"+{-# INLINE unsafeFromMap #-}++-- | /O(n)/. Build a non-empty map from a non-empty set of keys and+-- a function which for each key computes its value.+--+-- > fromSet (\k -> replicate k 'a') (Data.Set.NonEmpty.fromList (3 :| [5])) == fromList ((5,"aaaaa") :| [(3,"aaa")])+fromSet ::+ (k -> a) ->+ NESet k ->+ NEMap k a+fromSet f (NESet k ks) = NEMap k (f k) (M.fromSet f ks)+{-# INLINE fromSet #-}++-- | /O(log n)/. Lookup the value at a key in the map.+--+-- The function will return the corresponding value as @('Just' value)@,+-- or 'Nothing' if the key isn't in the map.+--+-- An example of using @lookup@:+--+-- > import Prelude hiding (lookup)+-- > import Data.Map.NonEmpty+-- >+-- > employeeDept = fromList (("John","Sales") :| [("Bob","IT")])+-- > deptCountry = fromList (("IT","USA") :| [("Sales","France")])+-- > countryCurrency = fromList (("USA", "Dollar") :| [("France", "Euro")])+-- >+-- > employeeCurrency :: String -> Maybe String+-- > employeeCurrency name = do+-- > dept <- lookup name employeeDept+-- > country <- lookup dept deptCountry+-- > lookup country countryCurrency+-- >+-- > main = do+-- > putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))+-- > putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))+--+-- The output of this program:+--+-- > John's currency: Just "Euro"+-- > Pete's currency: Nothing+lookup ::+ Ord k =>+ k ->+ NEMap k a ->+ Maybe a+lookup k (NEMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just v+ GT -> M.lookup k m+{-# INLINE lookup #-}++-- | /O(log n)/. Find the value at a key. Returns 'Nothing' when the+-- element can not be found.+--+-- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 1 == Nothing+-- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 5 == Just 'a'+(!?) :: Ord k => NEMap k a -> k -> Maybe a+(!?) = flip lookup+{-# INLINE (!?) #-}++-- | /O(log n)/. Find the value at a key. Calls 'error' when the element+-- can not be found.+--+-- > fromList ((5,'a') :| [(3,'b')]) ! 1 Error: element not in the map+-- > fromList ((5,'a') :| [(3,'b')]) ! 5 == 'a'+(!) :: Ord k => NEMap k a -> k -> a+(!) m k = fromMaybe e $ m !? k+ where+ e = error "NEMap.!: given key is not an element in the map"+{-# INLINE (!) #-}++infixl 9 !?+infixl 9 !++-- | /O(log n)/. The expression @('findWithDefault' def k map)@ returns+-- the value at key @k@ or returns default value @def@+-- when the key is not in the map.+--+-- > findWithDefault 'x' 1 (fromList ((5,'a') :| [(3,'b')])) == 'x'+-- > findWithDefault 'x' 5 (fromList ((5,'a') :| [(3,'b')])) == 'a'+findWithDefault ::+ Ord k =>+ a ->+ k ->+ NEMap k a ->+ a+findWithDefault def k (NEMap k0 v m) = case compare k k0 of+ LT -> def+ EQ -> v+ GT -> M.findWithDefault def k m+{-# INLINE findWithDefault #-}++-- | /O(log n)/. Is the key a member of the map? See also 'notMember'.+--+-- > member 5 (fromList ((5,'a') :| [(3,'b')])) == True+-- > member 1 (fromList ((5,'a') :| [(3,'b')])) == False+member :: Ord k => k -> NEMap k a -> Bool+member k (NEMap k0 _ m) = case compare k k0 of+ LT -> False+ EQ -> True+ GT -> M.member k m+{-# INLINE member #-}++-- | /O(log n)/. Is the key not a member of the map? See also 'member'.+--+-- > notMember 5 (fromList ((5,'a') :| [(3,'b')])) == False+-- > notMember 1 (fromList ((5,'a') :| [(3,'b')])) == True+notMember :: Ord k => k -> NEMap k a -> Bool+notMember k (NEMap k0 _ m) = case compare k k0 of+ LT -> True+ EQ -> False+ GT -> M.notMember k m+{-# INLINE notMember #-}++-- | /O(log n)/. Find largest key smaller than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupLT 3 (fromList ((3,'a') :| [(5,'b')])) == Nothing+-- > lookupLT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+lookupLT :: Ord k => k -> NEMap k a -> Maybe (k, a)+lookupLT k (NEMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Nothing+ GT -> M.lookupLT k m <|> Just (k0, v)+{-# INLINE lookupLT #-}++-- | /O(log n)/. Find smallest key greater than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupGT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+-- > lookupGT 5 (fromList ((3,'a') :| [(5,'b')])) == Nothing+lookupGT :: Ord k => k -> NEMap k a -> Maybe (k, a)+lookupGT k (NEMap k0 v m) = case compare k k0 of+ LT -> Just (k0, v)+ EQ -> M.lookupMin m+ GT -> M.lookupGT k m+{-# INLINE lookupGT #-}++-- | /O(log n)/. Find largest key smaller or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupLE 2 (fromList ((3,'a') :| [(5,'b')])) == Nothing+-- > lookupLE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+-- > lookupLE 5 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+lookupLE :: Ord k => k -> NEMap k a -> Maybe (k, a)+lookupLE k (NEMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just (k0, v)+ GT -> M.lookupLE k m <|> Just (k0, v)+{-# INLINE lookupLE #-}++-- | /O(log n)/. Find smallest key greater or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupGE 3 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+-- > lookupGE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+-- > lookupGE 6 (fromList ((3,'a') :| [(5,'b')])) == Nothing+lookupGE :: Ord k => k -> NEMap k a -> Maybe (k, a)+lookupGE k (NEMap k0 v m) = case compare k k0 of+ LT -> Just (k0, v)+ EQ -> Just (k0, v)+ GT -> M.lookupGE k m+{-# INLINE lookupGE #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union with a combining function.+--+-- > unionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "aA"), (7, "C")])+unionWith ::+ Ord k =>+ (a -> a -> a) ->+ NEMap k a ->+ NEMap k a ->+ NEMap k a+unionWith f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEMap k1 v1 . M.unionWith f m1 . toMap $ n2+ EQ -> NEMap k1 (f v1 v2) . M.unionWith f m1 $ m2+ GT -> NEMap k2 v2 . M.unionWith f (toMap n1) $ m2+{-# INLINE unionWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a possibly-empty+-- 'Map' and a non-empty map.+--+-- @since 0.3.6.0+unionMapLeft :: Ord k => Map k a -> NEMap k a -> NEMap k a+unionMapLeft m n = withNonEmpty n (`union` n) m+{-# INLINE unionMapLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a non-empty map and a+-- possibly-empty 'Map'.+--+-- @since 0.3.6.0+unionMapRight :: Ord k => NEMap k a -> Map k a -> NEMap k a+unionMapRight n = withNonEmpty n (union n)+{-# INLINE unionMapRight #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'Map' and a+-- non-empty map with a combining function.+--+-- @since 0.3.6.0+unionMapWithLeft :: Ord k => (a -> a -> a) -> Map k a -> NEMap k a -> NEMap k a+unionMapWithLeft f m n = withNonEmpty n (\m' -> unionWith f m' n) m+{-# INLINE unionMapWithLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a+-- possibly-empty 'Map' with a combining function.+--+-- @since 0.3.6.0+unionMapWithRight :: Ord k => (a -> a -> a) -> NEMap k a -> Map k a -> NEMap k a+unionMapWithRight f n = withNonEmpty n (unionWith f n)+{-# INLINE unionMapWithRight #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- Union with a combining function, given the matching key.+--+-- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value+-- > unionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "5:a|A"), (7, "C")])+unionWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ NEMap k a ->+ NEMap k a ->+ NEMap k a+unionWithKey f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEMap k1 v1 . M.unionWithKey f m1 . toMap $ n2+ EQ -> NEMap k1 (f k1 v1 v2) . M.unionWithKey f m1 $ m2+ GT -> NEMap k2 v2 . M.unionWithKey f (toMap n1) $ m2+{-# INLINE unionWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'Map' and a+-- non-empty map with a combining function, given the matching key.+--+-- @since 0.3.6.0+unionMapWithKeyLeft ::+ Ord k =>+ (k -> a -> a -> a) ->+ Map k a ->+ NEMap k a ->+ NEMap k a+unionMapWithKeyLeft f m n = withNonEmpty n (\m' -> unionWithKey f m' n) m+{-# INLINE unionMapWithKeyLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a+-- possibly-empty 'Map' with a combining function, given the matching key.+--+-- @since 0.3.6.0+unionMapWithKeyRight ::+ Ord k =>+ (k -> a -> a -> a) ->+ NEMap k a ->+ Map k a ->+ NEMap k a+unionMapWithKeyRight f n = withNonEmpty n (unionWithKey f n)+{-# INLINE unionMapWithKeyRight #-}++-- | The union of a non-empty list of maps, with a combining operation:+-- (@'unionsWith' f == 'Data.Foldable.foldl1' ('unionWith' f)@).+--+-- > unionsWith (++) (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])+-- > == fromList ((3, "bB3") :| [(5, "aAA3"), (7, "C")])+unionsWith ::+ (Foldable1 f, Ord k) =>+ (a -> a -> a) ->+ f (NEMap k a) ->+ NEMap k a+unionsWith f (F1.toNonEmpty -> (m :| ms)) = F.foldl' (unionWith f) m ms+{-# INLINE unionsWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Difference of two maps.+-- Return elements of the first map not existing in the second map.+--+-- Returns a potentially empty map ('Map'), in case the first map is+-- a subset of the second map.+--+-- > difference (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 3 "b"+difference ::+ Ord k =>+ NEMap k a ->+ NEMap k b ->+ Map k a+difference n1@(NEMap k1 v1 m1) n2@(NEMap k2 _ m2) = case compare k1 k2 of+ -- k1 is not in n2, so cannot be deleted+ LT -> insertMinMap k1 v1 $ m1 `M.difference` toMap n2+ -- k2 deletes k1, and only k1+ EQ -> m1 `M.difference` m2+ -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.+ GT -> toMap n1 `M.difference` m2+{-# INLINE difference #-}++-- | Same as 'difference'.+(\\) ::+ Ord k =>+ NEMap k a ->+ NEMap k b ->+ Map k a+(\\) = difference+{-# INLINE (\\) #-}++-- | /O(n+m)/. Difference with a combining function.+-- When two equal keys are+-- encountered, the combining function is applied to the values of these keys.+-- 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@.+--+-- Returns a potentially empty map ('Map'), in case the first map is+-- a subset of the second map and the function returns 'Nothing' for every+-- pair.+--+-- > let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing+-- > differenceWith f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (7, "C")]))+-- > == Data.Map.singleton 3 "b:B"+differenceWith ::+ Ord k =>+ (a -> b -> Maybe a) ->+ NEMap k a ->+ NEMap k b ->+ Map k a+differenceWith f = differenceWithKey (const f)+{-# INLINE differenceWith #-}++-- | /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@.+--+-- Returns a potentially empty map ('Map'), in case the first map is+-- a subset of the second map and the function returns 'Nothing' for every+-- pair.+--+-- > let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing+-- > differenceWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (10, "C")]))+-- > == Data.Map.singleton 3 "3:b|B"+differenceWithKey ::+ Ord k =>+ (k -> a -> b -> Maybe a) ->+ NEMap k a ->+ NEMap k b ->+ Map k a+differenceWithKey f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ -- k1 is not in n2, so cannot be deleted+ LT -> insertMinMap k1 v1 $ M.differenceWithKey f m1 (toMap n2)+ -- k2 deletes k1, and only k1+ EQ -> maybe id (insertMinMap k1) (f k1 v1 v2) (M.differenceWithKey f m1 m2)+ -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.+ GT -> M.differenceWithKey f (toMap n1) m2+{-# INLINE differenceWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection of two maps.+-- Return data in the first map for the keys existing in both maps.+-- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).+--+-- Returns a potentially empty map ('Map'), in case the two maps share no+-- keys in common.+--+-- > intersection (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 5 "a"+intersection ::+ Ord k =>+ NEMap k a ->+ NEMap k b ->+ Map k a+intersection n1@(NEMap k1 v1 m1) n2@(NEMap k2 _ m2) = case compare k1 k2 of+ -- k1 is not in n2+ LT -> m1 `M.intersection` toMap n2+ -- k1 and k2 are a part of the result+ EQ -> insertMinMap k1 v1 $ m1 `M.intersection` m2+ -- k2 is not in n1+ GT -> toMap n1 `M.intersection` m2+{-# INLINE intersection #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.+--+-- Returns a potentially empty map ('Map'), in case the two maps share no+-- keys in common.+--+-- > intersectionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 5 "aA"+intersectionWith ::+ Ord k =>+ (a -> b -> c) ->+ NEMap k a ->+ NEMap k b ->+ Map k c+intersectionWith f = intersectionWithKey (const f)+{-# INLINE intersectionWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.+--+-- Returns a potentially empty map ('Map'), in case the two maps share no+-- keys in common.+--+-- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar+-- > intersectionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 5 "5:a|A"+intersectionWithKey ::+ Ord k =>+ (k -> a -> b -> c) ->+ NEMap k a ->+ NEMap k b ->+ Map k c+intersectionWithKey f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ -- k1 is not in n2+ LT -> M.intersectionWithKey f m1 (toMap n2)+ -- k1 and k2 are a part of the result+ EQ -> insertMinMap k1 (f k1 v1 v2) $ M.intersectionWithKey f m1 m2+ -- k2 is not in n1+ GT -> M.intersectionWithKey f (toMap n1) m2+{-# INLINE intersectionWithKey #-}++-- | /O(n)/. A strict version of 'foldr1'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldr1' :: (a -> a -> a) -> NEMap k a -> a+foldr1' f (NEMap _ v m) = case M.maxView m of+ Nothing -> v+ Just (y, m') -> let !z = M.foldr' f y m' in v `f` z+{-# INLINE foldr1' #-}++-- | /O(n)/. A strict version of 'foldl1'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldl1' :: (a -> a -> a) -> NEMap k a -> a+foldl1' f (NEMap _ v m) = M.foldl' f v m+{-# INLINE foldl1' #-}++-- | /O(n)/. Fold the keys and values in the map using the given right-associative+-- binary operator, such that+-- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.+--+-- For example,+--+-- > keysList map = foldrWithKey (\k x ks -> k:ks) [] map+foldrWithKey :: (k -> a -> b -> b) -> b -> NEMap k a -> b+foldrWithKey f z (NEMap k v m) = f k v . M.foldrWithKey f z $ m+{-# INLINE foldrWithKey #-}++-- | /O(n)/. A strict version of 'foldrWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldrWithKey' :: (k -> a -> b -> b) -> b -> NEMap k a -> b+foldrWithKey' f z (NEMap k v m) = f k v y+ where+ !y = M.foldrWithKey f z m+{-# INLINE foldrWithKey' #-}++-- | /O(n)/. Fold the keys and values in the map using the given left-associative+-- binary operator, such that+-- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.+--+-- For example,+--+-- > keysList = reverse . foldlWithKey (\ks k x -> k:ks) []+foldlWithKey :: (a -> k -> b -> a) -> a -> NEMap k b -> a+foldlWithKey f z (NEMap k v m) = M.foldlWithKey f (f z k v) m+{-# INLINE foldlWithKey #-}++-- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldlWithKey' :: (a -> k -> b -> a) -> a -> NEMap k b -> a+foldlWithKey' f z (NEMap k v m) = M.foldlWithKey' f x m+ where+ !x = f z k v+{-# INLINE foldlWithKey' #-}++-- | /O(n)/. Return all keys of the map in ascending order.+--+-- > keys (fromList ((5,"a") :| [(3,"b")])) == (3 :| [5])+keys :: NEMap k a -> NonEmpty k+keys (NEMap k _ m) = k :| M.keys m+{-# INLINE keys #-}++-- | /O(n)/. An alias for 'toAscList'. Return all key\/value pairs in the map+-- in ascending key order.+--+-- > assocs (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+assocs :: NEMap k a -> NonEmpty (k, a)+assocs = toList+{-# INLINE assocs #-}++-- | /O(n)/. The non-empty set of all keys of the map.+--+-- > keysSet (fromList ((5,"a") :| [(3,"b")])) == Data.Set.NonEmpty.fromList (3 :| [5])+keysSet :: NEMap k a -> NESet k+keysSet (NEMap k _ m) = NESet k (M.keysSet m)+{-# INLINE keysSet #-}++-- | /O(n)/. Map a function over all values in the map.+--+-- > let f key x = (show key) ++ ":" ++ x+-- > mapWithKey f (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "3:b") :| [(5, "5:a")])+mapWithKey :: (k -> a -> b) -> NEMap k a -> NEMap k b+mapWithKey f (NEMap k v m) = NEMap k (f k v) (M.mapWithKey f m)+{-# NOINLINE [1] mapWithKey #-}++{-# RULES+"mapWithKey/mapWithKey" forall f g xs.+ mapWithKey f (mapWithKey g xs) =+ mapWithKey (\k a -> f k (g k a)) xs+"mapWithKey/map" forall f g xs.+ mapWithKey f (map g xs) =+ mapWithKey (\k a -> f k (g a)) xs+"map/mapWithKey" forall f g xs.+ map f (mapWithKey g xs) =+ mapWithKey (\k a -> f (g k a)) xs+ #-}++-- | /O(n)/. Convert the map to a list of key\/value pairs where the keys are+-- in ascending order.+--+-- > toAscList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+toAscList :: NEMap k a -> NonEmpty (k, a)+toAscList = toList+{-# INLINE toAscList #-}++-- | /O(n)/. Convert the map to a list of key\/value pairs where the keys+-- are in descending order.+--+-- > toDescList (fromList ((5,"a") :| [(3,"b")])) == ((5,"a") :| [(3,"b")])+toDescList :: NEMap k a -> NonEmpty (k, a)+toDescList (NEMap k0 v0 m) = M.foldlWithKey' go ((k0, v0) :| []) m+ where+ go xs k v = (k, v) NE.<| xs+{-# INLINE toDescList #-}++-- | /O(log n)/. Convert a 'Map' into an 'NEMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. If key is already present,+-- will overwrite the original value.+--+-- See 'insertMapMin' for a version that is constant-time if the new key is+-- /strictly smaller than/ all keys in the original map.+--+-- > insertMap 4 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])+-- > insertMap 4 "c" Data.Map.empty == singleton 4 "c"+insertMap :: Ord k => k -> a -> Map k a -> NEMap k a+insertMap k v = withNonEmpty (singleton k v) (insert k v)+{-# INLINE insertMap #-}++-- | /O(log n)/. Convert a 'Map' into an 'NEMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. Uses a combining function+-- with the new value as the first argument if the key is already present.+--+-- > insertMapWith (++) 4 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])+-- > insertMapWith (++) 5 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"ca")])+insertMapWith ::+ Ord k =>+ (a -> a -> a) ->+ k ->+ a ->+ Map k a ->+ NEMap k a+insertMapWith f k v = withNonEmpty (singleton k v) (insertWith f k v)+{-# INLINE insertMapWith #-}++-- | /O(log n)/. Convert a 'Map' into an 'NEMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. Uses a combining function+-- with the key and new value as the first and second arguments if the key+-- is already present.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "5:xxx|a")])+-- > insertWithKey f 7 "xxx" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+-- > insertWithKey f 5 "xxx" Data.Map.empty == singleton 5 "xxx"+insertMapWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ k ->+ a ->+ Map k a ->+ NEMap k a+insertMapWithKey f k v = withNonEmpty (singleton k v) (insertWithKey f k v)+{-# INLINE insertMapWithKey #-}++-- | /O(1)/ Convert a 'Map' into an 'NEMap' by adding a key-value pair+-- where the key is /strictly less than/ all keys in the input map. The+-- keys in the original map must all be /strictly greater than/ the new+-- key. /The precondition is not checked./+--+-- > insertMapMin 2 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((2,"c") :| [(3,"b"), (5,"a")])+-- > valid (insertMapMin 2 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == True+-- > valid (insertMapMin 7 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False+-- > valid (insertMapMin 3 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False+insertMapMin ::+ k ->+ a ->+ Map k a ->+ NEMap k a+insertMapMin = NEMap+{-# INLINE insertMapMin #-}++-- | /O(log n)/ Convert a 'Map' into an 'NEMap' by adding a key-value pair+-- where the key is /strictly greater than/ all keys in the input map. The+-- keys in the original map must all be /strictly less than/ the new+-- key. /The precondition is not checked./+--+-- While this has the same asymptotics as 'insertMap', it saves a constant+-- factor for key comparison (so may be helpful if comparison is expensive)+-- and also does not require an 'Ord' instance for the key type.+--+-- > insertMap 7 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"a"), (7,"c")])+-- > valid (insertMap 7 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == True+-- > valid (insertMap 2 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False+-- > valid (insertMap 5 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False+insertMapMax ::+ k ->+ a ->+ Map k a ->+ NEMap k a+insertMapMax k v = withNonEmpty (singleton k v) go+ where+ go (NEMap k0 v0 m0) = NEMap k0 v0 . insertMaxMap k v $ m0+{-# INLINE insertMapMax #-}++-- | /O(log n)/. Insert a new key and value in the map.+-- If the key is already present in the map, the associated value is+-- replaced with the supplied value. 'insert' is equivalent to+-- @'insertWith' 'const'@.+--+-- See 'insertMap' for a version where the first argument is a 'Map'.+--+-- > insert 5 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'x')])+-- > insert 7 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'a'), (7, 'x')])+insert ::+ Ord k =>+ k ->+ a ->+ NEMap k a ->+ NEMap k a+insert k v n@(NEMap k0 v0 m) = case compare k k0 of+ LT -> NEMap k v . toMap $ n+ EQ -> NEMap k v m+ GT -> NEMap k0 v0 . M.insert k v $ m+{-# INLINE insert #-}++-- | /O(log n)/. Insert with a function, combining key, new value and old+-- value. @'insertWithKey' f key value mp@ will insert the pair (key,+-- value) into @mp@ if key does not exist in the map. If the key does+-- exist, the function will insert the pair @(key,f key new_value+-- old_value)@. Note that the key passed to f is the same key passed to+-- 'insertWithKey'.+--+-- See 'insertMapWithKey' for a version where the first argument is a 'Map'.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:xxx|a")])+-- > insertWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+insertWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ k ->+ a ->+ NEMap k a ->+ NEMap k a+insertWithKey f k v n@(NEMap k0 v0 m) = case compare k k0 of+ LT -> NEMap k v . toMap $ n+ EQ -> NEMap k (f k v v0) m+ GT -> NEMap k0 v0 $ M.insertWithKey f k v m+{-# INLINE insertWithKey #-}++-- | /O(log n)/. Combines insert operation with old value retrieval. The+-- expression (@'insertLookupWithKey' f k x map@) is a pair where the first+-- element is equal to (@'lookup' k map@) and the second element equal to+-- (@'insertWithKey' f k x map@).+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertLookupWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "5:xxx|a")]))+-- > insertLookupWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "xxx")]))+--+-- This is how to define @insertLookup@ using @insertLookupWithKey@:+--+-- > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t+-- > insertLookup 5 "x" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "x")]))+-- > insertLookup 7 "x" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "x")]))+insertLookupWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ k ->+ a ->+ NEMap k a ->+ (Maybe a, NEMap k a)+insertLookupWithKey f k v n@(NEMap k0 v0 m) = case compare k k0 of+ LT -> (Nothing, NEMap k v . toMap $ n)+ EQ -> (Just v, NEMap k (f k v v0) m)+ GT -> NEMap k0 v0 <$> M.insertLookupWithKey f k v m+{-# INLINE insertLookupWithKey #-}++-- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs+-- with a combining function. See also 'fromAscListWith'.+--+-- > fromListWith (++) ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "ab") :| [(5, "aba")])+fromListWith ::+ Ord k =>+ (a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromListWith f = fromListWithKey (const f)+{-# INLINE fromListWith #-}++-- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs+-- with a combining function. See also 'fromAscListWithKey'.+--+-- > let f k a1 a2 = (show k) ++ a1 ++ a2+-- > fromListWithKey f ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "3ab") :| [(5, "5a5ba")])+fromListWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromListWithKey f ((k0, v0) :| xs) = F.foldl' go (singleton k0 v0) xs+ where+ go m (k, v) = insertWithKey f k v m+ {-# INLINE go #-}+{-# INLINE fromListWithKey #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time.+-- /The precondition (input list is ascending) is not checked./+--+-- > fromAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])+-- > fromAscList ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "b")])+-- > valid (fromAscList ((3,"b") :| [(5,"a"), (5,"b")])) == True+-- > valid (fromAscList ((5,"a") :| [(3,"b"), (5,"b")])) == False+fromAscList ::+ Eq k =>+ NonEmpty (k, a) ->+ NEMap k a+fromAscList = fromDistinctAscList . combineEq+{-# INLINE fromAscList #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is ascending) is not checked./+--+-- > fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "ba")])+-- > valid (fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b"))]) == True+-- > valid (fromAscListWith (++) ((5,"a") :| [(3,"b"), (5,"b"))]) == False+fromAscListWith ::+ Eq k =>+ (a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromAscListWith f = fromAscListWithKey (const f)+{-# INLINE fromAscListWith #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is ascending) is not checked./+--+-- > let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2+-- > fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")]) == fromList ((3, "b") :| [(5, "5:b5:ba")])+-- > valid (fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")])) == True+-- > valid (fromAscListWithKey f ((5,"a") :| [(3,"b"), (5,"b"), (5,"b")])) == False+fromAscListWithKey ::+ Eq k =>+ (k -> a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromAscListWithKey f = fromDistinctAscList . combineEqWith f+{-# INLINE fromAscListWithKey #-}++-- | /O(n)/. Build a map from an ascending non-empty list of distinct+-- elements in linear time. /The precondition is not checked./+--+-- > fromDistinctAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])+-- > valid (fromDistinctAscList ((3,"b") :| [(5,"a")])) == True+-- > valid (fromDistinctAscList ((3,"b") :| [(5,"a"), (5,"b")])) == False+fromDistinctAscList :: NonEmpty (k, a) -> NEMap k a+fromDistinctAscList ((k, v) :| xs) =+ insertMapMin k v+ . M.fromDistinctAscList+ $ xs+{-# INLINE fromDistinctAscList #-}++-- | /O(n)/. Build a map from a descending non-empty list in linear time.+-- /The precondition (input list is descending) is not checked./+--+-- > fromDescList ((5,"a") :| [(3,"b")]) == fromList ((3, "b") :| [(5, "a")])+-- > fromDescList ((5,"a") :| [(5,"b"), (3,"b")]) == fromList ((3, "b") :| [(5, "b")])+-- > valid (fromDescList ((5,"a") :| [(5,"b"), (3,"b")])) == True+-- > valid (fromDescList ((5,"a") :| [(3,"b"), (5,"b")])) == False+fromDescList ::+ Eq k =>+ NonEmpty (k, a) ->+ NEMap k a+fromDescList = fromDistinctDescList . combineEq+{-# INLINE fromDescList #-}++-- | /O(n)/. Build a map from a descending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is descending) is not checked./+--+-- > fromDescListWith (++) ((5,"a") :| [(5,"b"), (3,"b")]) == fromList ((3, "b") :| [(5, "ba")])+-- > valid (fromDescListWith (++) ((5,"a") :| [(5,"b"), (3,"b")])) == True+-- > valid (fromDescListWith (++) ((5,"a") :| [(3,"b"), (5,"b")])) == False+fromDescListWith ::+ Eq k =>+ (a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromDescListWith f = fromDescListWithKey (const f)+{-# INLINE fromDescListWith #-}++-- | /O(n)/. Build a map from a descending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is descending) is not checked./+--+-- > let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2+-- > fromDescListWithKey f ((5,"a") :| [(5,"b"), (5,"b"), (3,"b")]) == fromList ((3, "b") :| [(5, "5:b5:ba")])+-- > valid (fromDescListWithKey f ((5,"a") :| [(5,"b"), (5,"b"), (3,"b")])) == True+-- > valid (fromDescListWithKey f ((5,"a") :| [(3,"b"), (5,"b"), (5,"b")])) == False+fromDescListWithKey ::+ Eq k =>+ (k -> a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromDescListWithKey f = fromDistinctDescList . combineEqWith f+{-# INLINE fromDescListWithKey #-}++-- | /O(n)/. Build a map from a descending list of distinct elements in linear time.+-- /The precondition is not checked./+--+-- > fromDistinctDescList ((5,"a") :| [(3,"b")]) == fromList ((3, "b") :| [(5, "a")])+-- > valid (fromDistinctDescList ((5,"a") :| [(3,"b")])) == True+-- > valid (fromDistinctDescList ((5,"a") :| [(5,"b"), (3,"b")])) == False+--+-- @since 0.5.8+fromDistinctDescList :: NonEmpty (k, a) -> NEMap k a+fromDistinctDescList ((k, v) :| xs) =+ insertMapMax k v+ . M.fromDistinctDescList+ $ xs+{-# INLINE fromDistinctDescList #-}++-- | /O(log n)/. Delete a key and its value from the non-empty map.+-- A potentially empty map ('Map') is returned, since this might delete the+-- last item in the 'NEMap'. When the key is not a member of the map, is+-- equivalent to 'toMap'.+--+-- > delete 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- > delete 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.Singleton [(3, "b"), (5, "a")]+delete :: Ord k => k -> NEMap k a -> Map k a+delete k n@(NEMap k0 v m) = case compare k k0 of+ LT -> toMap n+ EQ -> m+ GT -> insertMinMap k0 v . M.delete k $ m+{-# INLINE delete #-}++-- | /O(log n)/. Delete a key and its value from the non-empty map, returning+-- 'Nothing' if the result would be empty.+--+-- This is more efficient than @'nonEmptyMap' . 'delete' k@ because it avoids+-- converting the known-minimum representation back through 'Map' when the+-- deleted key is not the minimum.+--+-- @since 0.3.6.0+deleteMaybe :: Ord k => k -> NEMap k a -> Maybe (NEMap k a)+deleteMaybe k n@(NEMap k0 v m) = case compare k k0 of+ LT -> Just n+ EQ -> nonEmptyMap m+ GT -> Just . NEMap k0 v . M.delete k $ m+{-# INLINE deleteMaybe #-}++-- | /O(log n)/. Update a value at a specific key with the result of the+-- provided function. When the key is not a member of the map, the original+-- map is returned.+--+-- > adjust ("new " ++) 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "new a")])+-- > adjust ("new " ++) 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])+adjust ::+ Ord k =>+ (a -> a) ->+ k ->+ NEMap k a ->+ NEMap k a+adjust f = adjustWithKey (const f)+{-# INLINE adjust #-}++-- | /O(log n)/. Adjust a value at a specific key. When the key is not+-- a member of the map, the original map is returned.+--+-- > let f key x = (show key) ++ ":new " ++ x+-- > adjustWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:new a")])+-- > adjustWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])+adjustWithKey ::+ Ord k =>+ (k -> a -> a) ->+ k ->+ NEMap k a ->+ NEMap k a+adjustWithKey f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> n+ EQ -> NEMap k0 (f k0 v) m+ GT -> NEMap k0 v . M.adjustWithKey f k $ m+{-# INLINE adjustWithKey #-}++-- | /O(log n)/. The expression (@'update' f k map@) updates the value @x@+-- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is+-- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.+--+-- Returns a potentially empty map ('Map'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEMap'.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > update f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "new a")]+-- > update f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a")]+-- > update f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+update ::+ Ord k =>+ (a -> Maybe a) ->+ k ->+ NEMap k a ->+ Map k a+update f = updateWithKey (const f)+{-# INLINE update #-}++-- | /O(log n)/. The expression (@'updateWithKey' f k map@) updates the+-- value @x@ at @k@ (if it is in the map). If (@f k x@) is 'Nothing',+-- the element is deleted. If it is (@'Just' y@), the key @k@ is bound+-- to the new value @y@.+--+-- Returns a potentially empty map ('Map'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEMap'.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "5:new a")]+-- > updateWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a")]+-- > updateWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+updateWithKey ::+ Ord k =>+ (k -> a -> Maybe a) ->+ k ->+ NEMap k a ->+ Map k a+updateWithKey f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> toMap n+ EQ -> maybe m (flip (insertMinMap k0) m) . f k0 $ v+ GT -> insertMinMap k0 v . M.updateWithKey f k $ m+{-# INLINE updateWithKey #-}++-- | /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 a potentially empty map ('Map') in the case that we delete the+-- final key of a singleton map.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateLookupWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == (Just "5:new a", Data.Map.fromList ((3, "b") :| [(5, "5:new a")]))+-- > updateLookupWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == (Nothing, Data.Map.fromList ((3, "b") :| [(5, "a")]))+-- > updateLookupWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == (Just "b", Data.Map.singleton 5 "a")+updateLookupWithKey ::+ Ord k =>+ (k -> a -> Maybe a) ->+ k ->+ NEMap k a ->+ (Maybe a, Map k a)+updateLookupWithKey f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> (Nothing, toMap n)+ EQ ->+ let u = f k0 v+ in (u <|> Just v, maybe m (flip (insertMinMap k0) m) u)+ GT -> fmap (insertMinMap k0 v) . M.updateLookupWithKey f k $ m+{-# INLINE updateLookupWithKey #-}++-- | /O(log n)/. The expression (@'alter' f k map@) alters the value @x@ at+-- @k@, or absence thereof. 'alter' can be used to insert, delete, or+-- update a value in a 'Map'. In short : @Data.Map.lookup k ('alter'+-- f k m) = f ('lookup' k m)@.+--+-- Returns a potentially empty map ('Map'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEMap'.+--+-- See 'alterF'' for a version that disallows deletion, and so therefore+-- can return 'NEMap'.+--+-- > let f _ = Nothing+-- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a")]+-- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- >+-- > let f _ = Just "c"+-- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a"), (7, "c")]+-- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "c")]+alter ::+ Ord k =>+ (Maybe a -> Maybe a) ->+ k ->+ NEMap k a ->+ Map k a+alter f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> maybe id (insertMinMap k) (f Nothing) (toMap n)+ EQ -> maybe id (insertMinMap k0) (f (Just v)) m+ GT -> insertMinMap k0 v . M.alter f k $ m+{-# INLINE alter #-}++-- | /O(log n)/. The expression (@'alterF' f k map@) alters the value @x@+-- at @k@, or absence thereof. 'alterF' can be used to inspect, insert,+-- delete, or update a value in a 'Map'. In short: @Data.Map.lookup+-- k \<$\> 'alterF' f k m = f ('lookup' k m)@.+--+-- Example:+--+-- @+-- interactiveAlter :: Int -> NEMap Int String -> IO (Map Int String)+-- interactiveAlter k m = alterF f k m where+-- f Nothing = do+-- putStrLn $ show k +++-- " was not found in the map. Would you like to add it?"+-- getUserResponse1 :: IO (Maybe String)+-- f (Just old) = do+-- putStrLn $ "The key is currently bound to " ++ show old +++-- ". Would you like to change or delete it?"+-- getUserResponse2 :: IO (Maybe String)+-- @+--+-- Like @Data.Map.alterF@ for 'Map', 'alterF' can be considered+-- to be a unifying generalization of 'lookup' and 'delete'; however, as+-- a constrast, it cannot be used to implement 'insert', because it must+-- return a 'Map' instead of an 'NEMap' (because the function might delete+-- the final item in the 'NEMap'). When used with trivial functors like+-- 'Identity' and 'Const', it is often slightly slower than+-- specialized 'lookup' and 'delete'. However, when the functor is+-- non-trivial and key comparison is not particularly cheap, it is the+-- fastest way.+--+-- See 'alterF'' for a version that disallows deletion, and so therefore+-- can return 'NEMap' and be used to implement 'insert'+--+-- Note on rewrite rules:+--+-- This module includes GHC rewrite rules to optimize 'alterF' for+-- the 'Const' and 'Identity' functors. In general, these rules+-- improve performance. The sole exception is that when using+-- 'Identity', deleting a key that is already absent takes longer+-- than it would without the rules. If you expect this to occur+-- a very large fraction of the time, you might consider using a+-- private copy of the 'Identity' type.+--+-- Note: Unlike @Data.Map.alterF@ for 'Map', 'alterF' is /not/ a flipped+-- version of the 'Control.Lens.At.at' combinator from "Control.Lens.At".+-- However, it match the shape expected from most functions expecting+-- lenses, getters, and setters, so can be thought of as a "psuedo-lens",+-- with virtually the same practical applications as a legitimate lens.+alterF ::+ (Ord k, Functor f) =>+ (Maybe a -> f (Maybe a)) ->+ k ->+ NEMap k a ->+ f (Map k a)+alterF f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> flip (maybe id (insertMinMap k)) (toMap n) <$> f Nothing+ EQ -> flip (maybe id (insertMinMap k0)) m <$> f (Just v)+ GT -> insertMinMap k0 v <$> M.alterF f k m+{-# INLINEABLE [2] alterF #-}++-- if f ~ Const b, it's a lookup+{-# RULES+"alterF/Const" forall k (f :: Maybe a -> Const b (Maybe a)).+ alterF f k =+ Const . getConst . f . lookup k+ #-}++-- if f ~ Identity, it's an 'alter'+{-# RULES+"alterF/Identity" forall k (f :: Maybe a -> Identity (Maybe a)).+ alterF f k =+ Identity . alter (runIdentity . f) k+ #-}++-- | /O(log n)/. Variant of 'alter' that disallows deletion. Allows us to+-- guarantee that the result is also a non-empty Map.+alter' ::+ Ord k =>+ (Maybe a -> a) ->+ k ->+ NEMap k a ->+ NEMap k a+alter' f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> NEMap k (f Nothing) . toMap $ n+ EQ -> NEMap k0 (f (Just v)) m+ GT -> NEMap k0 v . M.alter (Just . f) k $ m+{-# INLINE alter' #-}++-- | /O(log n)/. Variant of 'alterF' that disallows deletion. Allows us to+-- guarantee that the result is also a non-empty Map.+--+-- Like @Data.Map.alterF@ for 'Map', can be used to generalize and unify+-- 'lookup' and 'insert'. However, because it disallows deletion, it+-- cannot be used to implement 'delete'.+--+-- See 'alterF' for usage information and caveats.+--+-- Note: Neither 'alterF' nor 'alterF'' can be considered flipped versions+-- of the 'Control.Lens.At.at' combinator from "Control.Lens.At". However,+-- this can match the shape expected from most functions expecting lenses,+-- getters, and setters, so can be thought of as a "psuedo-lens", with+-- virtually the same practical applications as a legitimate lens.+--+-- __WARNING__: The rewrite rule for 'Identity' exposes an inconsistency in+-- undefined behavior for "Data.Map". @Data.Map.alterF@ will actually+-- /maintain/ the original key in the map when used with 'Identity';+-- however, @Data.Map.insertWith@ will /replace/ the orginal key in the+-- map. The rewrite rule for 'alterF'' has chosen to be faithful to+-- @Data.Map.insertWith@, and /not/ @Data.Map.alterF@, for the sake of+-- a cleaner implementation.+alterF' ::+ (Ord k, Functor f) =>+ (Maybe a -> f a) ->+ k ->+ NEMap k a ->+ f (NEMap k a)+alterF' f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> flip (NEMap k) (toMap n) <$> f Nothing+ EQ -> flip (NEMap k0) m <$> f (Just v)+ GT -> NEMap k0 v <$> M.alterF (fmap Just . f) k m+{-# INLINEABLE [2] alterF' #-}++-- if f ~ Const b, it's a lookup+{-# RULES+"alterF'/Const" forall k (f :: Maybe a -> Const b a).+ alterF' f k =+ Const . getConst . f . lookup k+ #-}++-- if f ~ Identity, it's an insertWith+{-# RULES+"alterF'/Identity" forall k (f :: Maybe a -> Identity a).+ alterF' f k =+ Identity . insertWith (\_ -> runIdentity . f . Just) k (runIdentity (f Nothing))+ #-}++-- | /O(n)/. Traverse keys\/values and collect the 'Just' results.+--+-- Returns a potentially empty map ('Map'), our function might return+-- 'Nothing' on every item in the 'NEMap'.+--+-- /Use 'traverseMaybeWithKey1'/ whenever possible (if your 'Applicative'+-- also has 'Apply' instance). This version is provided only for types+-- that do not have 'Apply' instance, since 'Apply' is not at the moment+-- (and might not ever be) an official superclass of 'Applicative'.+traverseMaybeWithKey ::+ Applicative t =>+ (k -> a -> t (Maybe b)) ->+ NEMap k a ->+ t (Map k b)+traverseMaybeWithKey f (NEMap k0 v m0) =+ combine <$> f k0 v <*> M.traverseMaybeWithKey f m0+ where+ combine Nothing = id+ combine (Just v') = insertMinMap k0 v'+{-# INLINE traverseMaybeWithKey #-}++-- | /O(n)/. Traverse keys\/values and collect the 'Just' results.+--+-- Returns a potentially empty map ('Map'), our function might return+-- 'Nothing' on every item in the 'NEMap'.+--+-- Is more general than 'traverseWithKey', since works with all 'Apply',+-- and not just 'Applicative'.++-- TODO: benchmark against M.maxView version+traverseMaybeWithKey1 ::+ Apply t =>+ (k -> a -> t (Maybe b)) ->+ NEMap k a ->+ t (Map k b)+traverseMaybeWithKey1 f (NEMap k0 v m0) = case runMaybeApply m1 of+ Left m2 -> combine <$> f k0 v <.> m2+ Right m2 -> (`combine` m2) <$> f k0 v+ where+ m1 = M.traverseMaybeWithKey (\k -> MaybeApply . Left . f k) m0+ combine Nothing = id+ combine (Just v') = insertMinMap k0 v'+{-# INLINE traverseMaybeWithKey1 #-}++-- | /O(n)/. The function 'mapAccum' threads an accumulating argument+-- through the map in ascending order of keys.+--+-- > let f a b = (a ++ b, b ++ "X")+-- > mapAccum f "Everything: " (fromList ((5,"a") :| [(3,"b")])) == ("Everything: ba", fromList ((3, "bX") :| [(5, "aX")]))+mapAccum ::+ (a -> b -> (a, c)) ->+ a ->+ NEMap k b ->+ (a, NEMap k c)+mapAccum f = mapAccumWithKey (\x _ -> f x)+{-# INLINE mapAccum #-}++-- | /O(n)/. The function 'mapAccumWithKey' threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")+-- > mapAccumWithKey f "Everything:" (fromList ((5,"a") :| [(3,"b")])) == ("Everything: 3-b 5-a", fromList ((3, "bX") :| [(5, "aX")]))+mapAccumWithKey ::+ (a -> k -> b -> (a, c)) ->+ a ->+ NEMap k b ->+ (a, NEMap k c)+mapAccumWithKey f z0 (NEMap k v m) = (z2, NEMap k v' m')+ where+ ~(z1, v') = f z0 k v+ ~(z2, m') = M.mapAccumWithKey f z1 m+{-# INLINE mapAccumWithKey #-}++-- | /O(n)/. The function 'mapAccumRWithKey' threads an accumulating+-- argument through the map in descending order of keys.+mapAccumRWithKey ::+ (a -> k -> b -> (a, c)) ->+ a ->+ NEMap k b ->+ (a, NEMap k c)+mapAccumRWithKey f z0 (NEMap k v m) = (z2, NEMap k v' m')+ where+ ~(z1, m') = M.mapAccumRWithKey f z0 m+ ~(z2, v') = f z1 k v+{-# INLINE mapAccumRWithKey #-}++-- TODO: what other situations can we take advantage of lazy tuple pattern+-- matching?++-- | /O(n*log n)/.+-- @'mapKeys' 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 value at the greatest of the+-- original keys is retained.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeys (+ 1) (fromList ((5,"a") :| [(3,"b")])) == fromList ((4, "b") :| [(6, "a")])+-- > mapKeys (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "c"+-- > mapKeys (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "c"+mapKeys ::+ Ord k2 =>+ (k1 -> k2) ->+ NEMap k1 a ->+ NEMap k2 a+mapKeys f (NEMap k0 v0 m) =+ fromListWith const+ . ((f k0, v0) :|)+ . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []+ $ m+{-# INLINEABLE mapKeys #-}++-- | /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@. The value at the greater of the two original keys+-- is used as the first argument to @c@.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeysWith (++) (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "cdab"+-- > mapKeysWith (++) (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "cdab"+mapKeysWith ::+ Ord k2 =>+ (a -> a -> a) ->+ (k1 -> k2) ->+ NEMap k1 a ->+ NEMap k2 a+mapKeysWith c f (NEMap k0 v0 m) =+ fromListWith c+ . ((f k0, v0) :|)+ . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []+ $ m+{-# INLINEABLE mapKeysWith #-}++-- | /O(n)/.+-- @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@+-- is strictly monotonic.+-- 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]+-- > ==> mapKeysMonotonic f s == mapKeys f s+-- > where ls = keys s+--+-- This means that @f@ maps distinct original keys to distinct resulting keys.+-- This function has better performance than 'mapKeys'.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")])) == fromList ((6, "b") :| [(10, "a")])+-- > valid (mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")]))) == True+-- > valid (mapKeysMonotonic (\ _ -> 1) (fromList ((5,"a") :| [(3,"b")]))) == False+mapKeysMonotonic ::+ (k1 -> k2) ->+ NEMap k1 a ->+ NEMap k2 a+mapKeysMonotonic f (NEMap k v m) =+ NEMap (f k) v+ . M.mapKeysMonotonic f+ $ m+{-# INLINE mapKeysMonotonic #-}++-- | /O(n)/. Filter all values that satisfy the predicate.+--+-- Returns a potentially empty map ('Map'), because we could+-- potentailly filter out all items in the original 'NEMap'.+--+-- > filter (> "a") (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- > filter (> "x") (fromList ((5,"a") :| [(3,"b")])) == Data.Map.empty+-- > filter (< "a") (fromList ((5,"a") :| [(3,"b")])) == Data.Map.empty+filter ::+ (a -> Bool) ->+ NEMap k a ->+ Map k a+filter f (NEMap k v m)+ | f v = insertMinMap k v . M.filter f $ m+ | otherwise = M.filter f m+{-# INLINE filter #-}++-- | /O(n)/. Filter all keys\/values that satisfy the predicate.+--+-- Returns a potentially empty map ('Map'), because we could+-- potentailly filter out all items in the original 'NEMap'.+--+-- > filterWithKey (\k _ -> k > 4) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+filterWithKey ::+ (k -> a -> Bool) ->+ NEMap k a ->+ Map k a+filterWithKey f (NEMap k v m)+ | f k v = insertMinMap k v . M.filterWithKey f $ m+ | otherwise = M.filterWithKey f m+{-# INLINE filterWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Restrict an 'NEMap' to only those keys+-- found in a 'Data.Set.Set'.+--+-- @+-- m \`restrictKeys\` s = 'filterWithKey' (\k _ -> k ``Set.member`` s) m+-- m \`restrictKeys\` s = m ``intersection`` 'fromSet' (const ()) s+-- @+restrictKeys ::+ Ord k =>+ NEMap k a ->+ Set k ->+ Map k a+restrictKeys n@(NEMap k v m) xs = case S.minView xs of+ Nothing -> M.empty+ Just (y, ys) -> case compare k y of+ -- k is not in xs+ LT -> m `M.restrictKeys` xs+ -- k and y are a part of the result+ EQ -> insertMinMap k v $ m `M.restrictKeys` ys+ -- y is not in m+ GT -> toMap n `M.restrictKeys` ys+{-# INLINE restrictKeys #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Remove all keys in a 'Data.Set.Set' from+-- an 'NEMap'.+--+-- @+-- m \`withoutKeys\` s = 'filterWithKey' (\k _ -> k ``Set.notMember`` s) m+-- m \`withoutKeys\` s = m ``difference`` 'fromSet' (const ()) s+-- @+withoutKeys ::+ Ord k =>+ NEMap k a ->+ Set k ->+ Map k a+withoutKeys n@(NEMap k v m) xs = case S.minView xs of+ Nothing -> toMap n+ Just (y, ys) -> case compare k y of+ -- k is not in xs, so cannot be deleted+ LT -> insertMinMap k v $ m `M.withoutKeys` xs+ -- y deletes k, and only k+ EQ -> m `M.withoutKeys` ys+ -- y is not in n, so cannot delete anything, so we can just difference n and ys+ GT -> toMap n `M.withoutKeys` ys+{-# INLINE withoutKeys #-}++-- | /O(n)/. Partition the map according to a predicate.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate was true for all items.+-- * @'That' n2@ means that the predicate was false for all items.+-- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the+-- predicate) and @n2@ (all of the items that were false for the+-- predicate).+--+-- See also 'split'.+--+-- > partition (> "a") (fromList ((5,"a") :| [(3,"b")])) == These (singleton 3 "b") (singleton 5 "a")+-- > partition (< "x") (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))+-- > partition (> "x") (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))+partition ::+ (a -> Bool) ->+ NEMap k a ->+ These (NEMap k a) (NEMap k a)+partition f = partitionWithKey (const f)+{-# INLINE partition #-}++-- | /O(n)/. Partition the map according to a predicate.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate was true for all items,+-- returning the original map.+-- * @'That' n2@ means that the predicate was false for all items,+-- returning the original map.+-- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the+-- predicate) and @n2@ (all of the items that were false for the+-- predicate).+--+-- See also 'split'.+--+-- > partitionWithKey (\ k _ -> k > 3) (fromList ((5,"a") :| [(3,"b")])) == These (singleton 5 "a") (singleton 3 "b")+-- > partitionWithKey (\ k _ -> k < 7) (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))+-- > partitionWithKey (\ k _ -> k > 7) (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))+partitionWithKey ::+ (k -> a -> Bool) ->+ NEMap k a ->+ These (NEMap k a) (NEMap k a)+partitionWithKey f n@(NEMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing)+ | f k v -> This n+ | otherwise -> That n+ (Just n1, Nothing)+ | f k v -> This n+ | otherwise -> These n1 (singleton k v)+ (Nothing, Just n2)+ | f k v -> These (singleton k v) n2+ | otherwise -> That n+ (Just n1, Just n2)+ | f k v -> These (insertMapMin k v m1) n2+ | otherwise -> These n1 (insertMapMin k v m2)+ where+ (m1, m2) = M.partitionWithKey f m0+{-# INLINEABLE partitionWithKey #-}++-- | /O(log n)/. Take while a predicate on the keys holds.+-- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,+-- @j \< k ==\> p j \>= p k@. See note at 'spanAntitone'.+--+-- Returns a potentially empty map ('Map'), because the predicate might+-- fail on the first input.+--+-- @+-- takeWhileAntitone p = Data.Map.fromDistinctAscList . Data.List.takeWhile (p . fst) . Data.Foldable.toList+-- takeWhileAntitone p = 'filterWithKey' (\k _ -> p k)+-- @+takeWhileAntitone ::+ (k -> Bool) ->+ NEMap k a ->+ Map k a+takeWhileAntitone f (NEMap k v m)+ | f k = insertMinMap k v . M.takeWhileAntitone f $ m+ | otherwise = M.empty+{-# INLINE takeWhileAntitone #-}++-- | /O(log n)/. Drop while a predicate on the keys holds.+-- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,+-- @j \< k ==\> p j \>= p k@. See note at 'spanAntitone'.+--+-- @+-- dropWhileAntitone p = Data.Map.fromDistinctAscList . Data.List.dropWhile (p . fst) . Data.Foldable.toList+-- dropWhileAntitone p = 'filterWithKey' (\k -> not (p k))+-- @+dropWhileAntitone ::+ (k -> Bool) ->+ NEMap k a ->+ Map k a+dropWhileAntitone f n@(NEMap k _ m)+ | f k = M.dropWhileAntitone f m+ | otherwise = toMap n+{-# INLINE dropWhileAntitone #-}++-- | /O(log n)/. Divide a map at the point where a predicate on the keys stops holding.+-- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,+-- @j \< k ==\> p j \>= p k@.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate never failed for any item,+-- returning the original map.+-- * @'That' n2@ means that the predicate failed for the first item,+-- returning the original map.+-- * @'These' n1 n2@ gives @n1@ (the map up to the point where the+-- predicate on the keys stops holding) and @n2@ (the map starting from+-- the point where the predicate stops holding)+--+-- @+-- spanAntitone p xs = partitionWithKey (\k _ -> p k) xs+-- @+--+-- Note: if @p@ is not actually antitone, then @spanAntitone@ will split the map+-- at some /unspecified/ point where the predicate switches from holding to not+-- holding (where the predicate is seen to hold before the first key and to fail+-- after the last key).+spanAntitone ::+ (k -> Bool) ->+ NEMap k a ->+ These (NEMap k a) (NEMap k a)+spanAntitone f n@(NEMap k v m0)+ | f k = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This n+ (Just _, Nothing) -> This n+ (Nothing, Just n2) -> These (singleton k v) n2+ (Just _, Just n2) -> These (insertMapMin k v m1) n2+ | otherwise = That n+ where+ (m1, m2) = M.spanAntitone f m0+{-# INLINEABLE spanAntitone #-}++-- | /O(n)/. Map values and collect the 'Just' results.+--+-- Returns a potentially empty map ('Map'), because the function could+-- potentially return 'Nothing' on all items in the 'NEMap'.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > mapMaybe f (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "new a"+mapMaybe ::+ (a -> Maybe b) ->+ NEMap k a ->+ Map k b+mapMaybe f = mapMaybeWithKey (const f)+{-# INLINE mapMaybe #-}++-- | /O(n)/. Map keys\/values and collect the 'Just' results.+--+-- Returns a potentially empty map ('Map'), because the function could+-- potentially return 'Nothing' on all items in the 'NEMap'.+--+-- > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing+-- > mapMaybeWithKey f (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "key : 3"+mapMaybeWithKey ::+ (k -> a -> Maybe b) ->+ NEMap k a ->+ Map k b+mapMaybeWithKey f (NEMap k v m) = maybe id (insertMinMap k) (f k v) (M.mapMaybeWithKey f m)+{-# INLINE mapMaybeWithKey #-}++-- | /O(n)/. Map values and separate the 'Left' and 'Right' results.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the results were all 'Left'.+-- * @'That' n2@ means that the results were all 'Right'.+-- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')+-- and @n2@ (the map where the results were 'Right')+--+-- > let f a = if a < "c" then Left a else Right a+-- > mapEither f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == These (fromList ((3,"b") :| [(5,"a")])) (fromList ((1,"x") :| [(7,"z")]))+-- >+-- > mapEither (\ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == That (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+mapEither ::+ (a -> Either b c) ->+ NEMap k a ->+ These (NEMap k b) (NEMap k c)+mapEither f = mapEitherWithKey (const f)+{-# INLINE mapEither #-}++-- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the results were all 'Left'.+-- * @'That' n2@ means that the results were all 'Right'.+-- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')+-- and @n2@ (the map where the results were 'Right')+--+-- > let f k a = if k < 5 then Left (k * 2) else Right (a ++ a)+-- > mapEitherWithKey f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == These (fromList ((1,2) :| [(3,6)])) (fromList ((5,"aa") :| [(7,"zz")]))+-- >+-- > mapEitherWithKey (\_ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == That (fromList ((1,"x") :| [(3,"b"), (5,"a"), (7,"z")]))+mapEitherWithKey ::+ (k -> a -> Either b c) ->+ NEMap k a ->+ These (NEMap k b) (NEMap k c)+mapEitherWithKey f (NEMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> case f k v of+ Left v' -> This (singleton k v')+ Right v' -> That (singleton k v')+ (Just n1, Nothing) -> case f k v of+ Left v' -> This (insertMapMin k v' m1)+ Right v' -> These n1 (singleton k v')+ (Nothing, Just n2) -> case f k v of+ Left v' -> These (singleton k v') n2+ Right v' -> That (insertMapMin k v' m2)+ (Just n1, Just n2) -> case f k v of+ Left v' -> These (insertMapMin k v' m1) n2+ Right v' -> These n1 (insertMapMin k v' m2)+ where+ (m1, m2) = M.mapEitherWithKey f m0+{-# INLINEABLE mapEitherWithKey #-}++-- | /O(log n)/. The expression (@'split' k map@) is potentially a 'These'+-- containing up to two 'NEMap's based on splitting the map into maps+-- containing items before and after the given key @k@. It will never+-- return a map that contains @k@ itself.+--+-- * 'Nothing' means that @k@ was the only key in the the original map,+-- and so there are no items before or after it.+-- * @'Just' ('This' n1)@ means @k@ was larger than or equal to all items+-- in the map, and @n1@ is the entire original map (minus @k@, if it was+-- present)+-- * @'Just' ('That' n2)@ means @k@ was smaller than or equal to all+-- items in the map, and @n2@ is the entire original map (minus @k@, if+-- it was present)+-- * @'Just' ('These' n1 n2)@ gives @n1@ (the map of all keys from the+-- original map less than @k@) and @n2@ (the map of all keys from the+-- original map greater than @k@)+--+-- > split 2 (fromList ((5,"a") :| [(3,"b")])) == Just (That (fromList ((3,"b") :| [(5,"a")])) )+-- > split 3 (fromList ((5,"a") :| [(3,"b")])) == Just (That (singleton 5 "a") )+-- > split 4 (fromList ((5,"a") :| [(3,"b")])) == Just (These (singleton 3 "b") (singleton 5 "a"))+-- > split 5 (fromList ((5,"a") :| [(3,"b")])) == Just (This (singleton 3 "b") )+-- > split 6 (fromList ((5,"a") :| [(3,"b")])) == Just (This (fromList ((3,"b") :| [(5,"a")])) )+-- > split 5 (singleton 5 "a") == Nothing+split ::+ Ord k =>+ k ->+ NEMap k a ->+ Maybe (These (NEMap k a) (NEMap k a))+split k n@(NEMap k0 v m0) = case compare k k0 of+ LT -> Just $ That n+ EQ -> That <$> nonEmptyMap m0+ GT -> Just $ case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k0 v)+ (Just _, Nothing) -> This (insertMapMin k0 v m1)+ (Nothing, Just n2) -> These (singleton k0 v) n2+ (Just _, Just n2) -> These (insertMapMin k0 v m1) n2+ where+ (m1, m2) = M.split k m0+{-# INLINEABLE split #-}++-- | /O(log n)/. The expression (@'splitLookup' k map@) splits a map just+-- like 'split' but also returns @'lookup' k map@, as the first field in+-- the 'These':+--+-- > splitLookup 2 (fromList ((5,"a") :| [(3,"b")])) == That (That (fromList ((3,"b") :| [(5,"a")])))+-- > splitLookup 3 (fromList ((5,"a") :| [(3,"b")])) == These "b" (That (singleton 5 "a"))+-- > splitLookup 4 (fromList ((5,"a") :| [(3,"b")])) == That (These (singleton 3 "b") (singleton 5 "a"))+-- > splitLookup 5 (fromList ((5,"a") :| [(3,"b")])) == These "a" (This (singleton 3 "b"))+-- > splitLookup 6 (fromList ((5,"a") :| [(3,"b")])) == That (This (fromList ((3,"b") :| [(5,"a")])))+-- > splitLookup 5 (singleton 5 "a") == This "a"+splitLookup ::+ Ord k =>+ k ->+ NEMap k a ->+ These a (These (NEMap k a) (NEMap k a))+splitLookup k n@(NEMap k0 v0 m0) = case compare k k0 of+ LT -> That . That $ n+ EQ -> maybe (This v0) (These v0 . That) . nonEmptyMap $ m0+ GT -> maybe That These v $ case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k0 v0)+ (Just _, Nothing) -> This (insertMapMin k0 v0 m1)+ (Nothing, Just n2) -> These (singleton k0 v0) n2+ (Just _, Just n2) -> These (insertMapMin k0 v0 m1) n2+ where+ (m1, v, m2) = M.splitLookup k m0+{-# INLINEABLE splitLookup #-}++-- | /O(1)/. Decompose a map into pieces based on the structure of the+-- underlying tree. This function is useful for consuming a map in+-- parallel.+--+-- No guarantee is made as to the sizes of the pieces; an internal, but+-- deterministic process determines this. However, it is guaranteed that+-- the pieces returned will be in ascending order (all elements in the+-- first submap less than all elements in the second, and so on).+--+-- Note that the current implementation does not return more than four+-- submaps, but you should not depend on this behaviour because it can+-- change in the future without notice.+splitRoot ::+ NEMap k a ->+ NonEmpty (NEMap k a)+splitRoot (NEMap k v m) =+ singleton k v+ :| Maybe.mapMaybe nonEmptyMap (M.splitRoot m)+{-# INLINE splitRoot #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).+isSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool+isSubmapOf = isSubmapOfBy (==)+{-# INLINE isSubmapOf #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if+-- all keys in @t1@ are in tree @t2@, and when @f@ returns 'True' when+-- applied to their respective values. For example, the following+-- expressions are all 'True':+--+-- > isSubmapOfBy (==) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (<=) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (fromList (('a',1) :| [('b',2)]))+--+-- But the following are all 'False':+--+-- > isSubmapOfBy (==) (singleton 'a' 2) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (<) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (singleton 'a' 1)+isSubmapOfBy ::+ Ord k =>+ (a -> b -> Bool) ->+ NEMap k a ->+ NEMap k b ->+ Bool+isSubmapOfBy f (NEMap k v m0) (toMap -> m1) =+ kvSub+ && M.isSubmapOfBy f m0 m1+ where+ kvSub = case M.lookup k m1 of+ Just v0 -> f v v0+ Nothing -> False+{-# INLINE isSubmapOfBy #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Is this a proper submap? (ie. a submap+-- but not equal). Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy'+-- (==)@).+isProperSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool+isProperSubmapOf = isProperSubmapOfBy (==)+{-# INLINE isProperSubmapOf #-}++-- | /O(m*log(n\/m + 1)), m <= n/. 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 values. For+-- example, the following expressions are all 'True':+--+-- > isProperSubmapOfBy (==) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+-- > isProperSubmapOfBy (<=) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+--+-- But the following are all 'False':+--+-- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (fromList ((1,1) :| [(2,2)]))+-- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (singleton 1 1))+-- > isProperSubmapOfBy (<) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+isProperSubmapOfBy ::+ Ord k =>+ (a -> b -> Bool) ->+ NEMap k a ->+ NEMap k b ->+ Bool+isProperSubmapOfBy f m1 m2 =+ M.size (nemMap m1) < M.size (nemMap m2)+ && isSubmapOfBy f m1 m2+{-# INLINE isProperSubmapOfBy #-}++-- | /O(log n)/. Lookup the /index/ of a key, which is its zero-based index+-- in the sequence sorted by keys. The index is a number from /0/ up to,+-- but not including, the 'size' of the map.+--+-- > isJust (lookupIndex 2 (fromList ((5,"a") :| [(3,"b")]))) == False+-- > fromJust (lookupIndex 3 (fromList ((5,"a") :| [(3,"b")]))) == 0+-- > fromJust (lookupIndex 5 (fromList ((5,"a") :| [(3,"b")]))) == 1+-- > isJust (lookupIndex 6 (fromList ((5,"a") :| [(3,"b")]))) == False+lookupIndex ::+ Ord k =>+ k ->+ NEMap k a ->+ Maybe Int+lookupIndex k (NEMap k0 _ m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just 0+ GT -> (+ 1) <$> M.lookupIndex k m+{-# INLINE lookupIndex #-}++-- | /O(log n)/. Return the /index/ of a key, which is its zero-based index+-- in the sequence sorted by keys. The index is a number from /0/ up to,+-- but not including, the 'size' of the map. Calls 'error' when the key is+-- not a 'member' of the map.+--+-- > findIndex 2 (fromList ((5,"a") :| [(3,"b")])) Error: element is not in the map+-- > findIndex 3 (fromList ((5,"a") :| [(3,"b")])) == 0+-- > findIndex 5 (fromList ((5,"a") :| [(3,"b")])) == 1+-- > findIndex 6 (fromList ((5,"a") :| [(3,"b")])) Error: element is not in the map+findIndex ::+ Ord k =>+ k ->+ NEMap k a ->+ Int+findIndex k = fromMaybe e . lookupIndex k+ where+ e = error "NEMap.findIndex: element is not in the map"+{-# INLINE findIndex #-}++-- | /O(log n)/. Retrieve an element by its /index/, i.e. by its zero-based+-- index in the sequence sorted by keys. If the /index/ is out of range+-- (less than zero, greater or equal to 'size' of the map), 'error' is+-- called.+--+-- > elemAt 0 (fromList ((5,"a") :| [(3,"b")])) == (3,"b")+-- > elemAt 1 (fromList ((5,"a") :| [(3,"b")])) == (5, "a")+-- > elemAt 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+elemAt ::+ Int ->+ NEMap k a ->+ (k, a)+elemAt 0 (NEMap k v _) = (k, v)+elemAt i (NEMap _ _ m) = M.elemAt (i - 1) m+{-# INLINEABLE elemAt #-}++-- | /O(log n)/. Update the element at /index/, i.e. by its zero-based index in+-- the sequence sorted by keys. If the /index/ is out of range (less than zero,+-- greater or equal to 'size' of the map), 'error' is called.+--+-- Returns a possibly empty map ('Map'), because the function might end up+-- deleting the last key in the map. See 'adjustAt' for a version that+-- disallows deletion, guaranteeing that the result is also a non-empty+-- Map.+--+-- > updateAt (\ _ _ -> Just "x") 0 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "x"), (5, "a")]+-- > updateAt (\ _ _ -> Just "x") 1 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "x")]+-- > updateAt (\ _ _ -> Just "x") 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+-- > updateAt (\ _ _ -> Just "x") (-1) (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+-- > updateAt (\_ _ -> Nothing) 0 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+-- > updateAt (\_ _ -> Nothing) 1 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- > updateAt (\_ _ -> Nothing) 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+-- > updateAt (\_ _ -> Nothing) (-1) (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+updateAt ::+ (k -> a -> Maybe a) ->+ Int ->+ NEMap k a ->+ Map k a+updateAt f 0 (NEMap k v m) = maybe m (flip (insertMinMap k) m) $ f k v+updateAt f i (NEMap k v m) = insertMinMap k v . M.updateAt f (i - 1) $ m+{-# INLINEABLE updateAt #-}++-- | /O(log n)/. Variant of 'updateAt' that disallows deletion. Allows us+-- to guarantee that the result is also a non-empty Map.+adjustAt ::+ (k -> a -> a) ->+ Int ->+ NEMap k a ->+ NEMap k a+adjustAt f 0 (NEMap k0 v m) = NEMap k0 (f k0 v) m+adjustAt f i (NEMap k0 v m) =+ NEMap k0 v+ . M.updateAt (\k -> Just . f k) (i - 1)+ $ m+{-# INLINEABLE adjustAt #-}++-- | /O(log n)/. Delete the element at /index/, i.e. by its zero-based+-- index in the sequence sorted by keys. If the /index/ is out of range+-- (less than zero, greater or equal to 'size' of the map), 'error' is+-- called.+--+-- Returns a potentially empty map ('Map') because of the possibility of+-- deleting the last item in a map.+--+-- > deleteAt 0 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+-- > deleteAt 1 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- > deleteAt 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+-- > deleteAt (-1) (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+deleteAt ::+ Int ->+ NEMap k a ->+ Map k a+deleteAt 0 (NEMap _ _ m) = m+deleteAt i (NEMap k v m) = insertMinMap k v . M.deleteAt (i - 1) $ m+{-# INLINEABLE deleteAt #-}++-- | Take a given number of entries in key order, beginning with the+-- smallest keys.+--+-- Returns a possibly empty map ('Map'), which can only happen if we call+-- @take 0@.+--+-- @+-- take n = Data.Map.fromDistinctAscList . Data.List.NonEmpty.take n . 'toList'+-- @+take ::+ Int ->+ NEMap k a ->+ Map k a+take 0 NEMap{} = M.empty+take i (NEMap k v m) = insertMinMap k v . M.take (i - 1) $ m+{-# INLINEABLE take #-}++-- | Drop a given number of entries in key order, beginning+-- with the smallest keys.+--+-- Returns a possibly empty map ('Map'), in case we drop all of the+-- elements (which can happen if we drop a number greater than or equal to+-- the number of items in the map)+--+-- @+-- drop n = Data.Map.fromDistinctAscList . Data.List.NonEmpty.drop' n . 'toList'+-- @+drop ::+ Int ->+ NEMap k a ->+ Map k a+drop 0 n = toMap n+drop i (NEMap _ _ m) = M.drop (i - 1) m+{-# INLINEABLE drop #-}++-- | /O(log n)/. Split a map at a particular index @i@.+--+-- * @'This' n1@ means that there are less than @i@ items in the map, and+-- @n1@ is the original map.+-- * @'That' n2@ means @i@ was 0; we dropped 0 items, so @n2@ is the+-- original map.+-- * @'These' n1 n2@ gives @n1@ (taking @i@ items from the original map)+-- and @n2@ (dropping @i@ items from the original map))+splitAt ::+ Int ->+ NEMap k a ->+ These (NEMap k a) (NEMap k a)+splitAt 0 n = That n+splitAt i n@(NEMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k v)+ (Just _, Nothing) -> This n+ (Nothing, Just n2) -> These (singleton k v) n2+ (Just _, Just n2) -> These (insertMapMin k v m1) n2+ where+ (m1, m2) = M.splitAt (i - 1) m0+{-# INLINEABLE splitAt #-}++-- | /O(1)/. The minimal key of the map. Note that this is total, making+-- 'Data.Map.lookupMin' obsolete. It is constant-time, so has better+-- asymptotics than @Data.Map.lookupMin@ and @Data.Map.findMin@, as well.+--+-- > findMin (fromList ((5,"a") :| [(3,"b")])) == (3,"b")+findMin :: NEMap k a -> (k, a)+findMin (NEMap k v _) = (k, v)+{-# INLINE findMin #-}++-- | /O(log n)/. The maximal key of the map. Note that this is total, making+-- 'Data.Map.lookupMin' obsolete.+--+-- > findMax (fromList ((5,"a") :| [(3,"b")])) == (5,"a")+findMax :: NEMap k a -> (k, a)+findMax (NEMap k v m) = fromMaybe (k, v) . M.lookupMax $ m+{-# INLINE findMax #-}++-- | /O(1)/. Delete the minimal key. Returns a potentially empty map+-- ('Map'), because we might end up deleting the final key in a singleton+-- map. It is constant-time, so has better asymptotics than+-- 'Data.Map.deleteMin'.+--+-- > deleteMin (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.Map.fromList [(5,"a"), (7,"c")]+-- > deleteMin (singleton 5 "a") == Data.Map.empty+deleteMin :: NEMap k a -> Map k a+deleteMin (NEMap _ _ m) = m+{-# INLINE deleteMin #-}++-- | /O(log n)/. Delete the maximal key. Returns a potentially empty map+-- ('Map'), because we might end up deleting the final key in a singleton+-- map.+--+-- > deleteMax (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.Map.fromList [(3,"b"), (5,"a")]+-- > deleteMax (singleton 5 "a") == Data.Map.empty+deleteMax :: NEMap k a -> Map k a+deleteMax (NEMap k v m) = case M.maxView m of+ Nothing -> M.empty+ Just (_, m') -> insertMinMap k v m'+{-# INLINE deleteMax #-}++-- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the+-- minimal key. Returns a potentially empty map ('Map'), because we might+-- end up deleting the final key in the map if the function returns+-- 'Nothing'. See 'adjustMin' for a version that can guaruntee that we+-- return a non-empty map.+--+-- > updateMin (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "Xb"), (5, "a")]+-- > updateMin (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+updateMin :: (a -> Maybe a) -> NEMap k a -> Map k a+updateMin f = updateMinWithKey (const f)+{-# INLINE updateMin #-}++-- | /O(1)/. A version of 'updateMin' that disallows deletion, allowing us+-- to guarantee that the result is also non-empty.+adjustMin :: (a -> a) -> NEMap k a -> NEMap k a+adjustMin f = adjustMinWithKey (const f)+{-# INLINE adjustMin #-}++-- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the+-- minimal key. Returns a potentially empty map ('Map'), because we might+-- end up deleting the final key in the map if the function returns+-- 'Nothing'. See 'adjustMinWithKey' for a version that guaruntees+-- a non-empty map.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+updateMinWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a+updateMinWithKey f (NEMap k v m) = maybe id (insertMinMap k) (f k v) m+{-# INLINE updateMinWithKey #-}++-- | /O(1)/. A version of 'adjustMaxWithKey' that disallows deletion,+-- allowing us to guarantee that the result is also non-empty. Note that+-- it also is able to have better asymptotics than 'updateMinWithKey' in+-- general.+adjustMinWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a+adjustMinWithKey f (NEMap k v m) = NEMap k (f k v) m+{-# INLINE adjustMinWithKey #-}++-- | /O(log n)/. Update the value at the maximal key. Returns+-- a potentially empty map ('Map'), because we might end up deleting the+-- final key in the map if the function returns 'Nothing'. See 'adjustMax'+-- for a version that can guarantee that we return a non-empty map.+--+-- > updateMax (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "Xa")]+-- > updateMax (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+updateMax :: (a -> Maybe a) -> NEMap k a -> Map k a+updateMax f = updateMaxWithKey (const f)+{-# INLINE updateMax #-}++-- | /O(log n)/. A version of 'updateMax' that disallows deletion, allowing+-- us to guarantee that the result is also non-empty.+adjustMax :: (a -> a) -> NEMap k a -> NEMap k a+adjustMax f = adjustMaxWithKey (const f)+{-# INLINE adjustMax #-}++-- | /O(log n)/. Update the value at the maximal key. Returns+-- a potentially empty map ('Map'), because we might end up deleting the+-- final key in the map if the function returns 'Nothing'. See+-- 'adjustMaxWithKey' for a version that guaruntees a non-empty map.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+updateMaxWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a+updateMaxWithKey f (NEMap k v m)+ | M.null m = maybe m (M.singleton k) $ f k v+ | otherwise =+ insertMinMap k v+ . M.updateMaxWithKey f+ $ m+{-# INLINE updateMaxWithKey #-}++-- | /O(log n)/. A version of 'updateMaxWithKey' that disallows deletion,+-- allowing us to guarantee that the result is also non-empty.+adjustMaxWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a+adjustMaxWithKey f (NEMap k0 v m)+ | M.null m = NEMap k0 (f k0 v) m+ | otherwise =+ insertMapMin k0 v+ . M.updateMaxWithKey (\k -> Just . f k)+ $ m+{-# INLINE adjustMaxWithKey #-}++-- | /O(1)/. Retrieves the value associated with minimal key of the+-- map, and the map stripped of that element. It is constant-time, so has+-- better asymptotics than @Data.Map.minView@ for 'Map'.+--+-- Note that unlike @Data.Map.minView@ for 'Map', this cannot ever fail,+-- so doesn't need to return in a 'Maybe'. However, the result 'Map' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > minView (fromList ((5,"a") :| [(3,"b")])) == ("b", Data.Map.singleton 5 "a")+minView :: NEMap k a -> (a, Map k a)+minView = first snd . deleteFindMin+{-# INLINE minView #-}++-- | /O(1)/. Delete and find the minimal key-value pair. It is+-- constant-time, so has better asymptotics that @Data.Map.minView@ for+-- 'Map'.+--+-- Note that unlike @Data.Map.deleteFindMin@ for 'Map', this cannot ever+-- fail, and so is a total function. However, the result 'Map' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > deleteFindMin (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((3,"b"), Data.Map.fromList [(5,"a"), (10,"c")])+deleteFindMin :: NEMap k a -> ((k, a), Map k a)+deleteFindMin (NEMap k v m) = ((k, v), m)+{-# INLINE deleteFindMin #-}++-- | /O(log n)/. Retrieves the value associated with maximal key of the+-- map, and the map stripped of that element.+--+-- Note that unlike @Data.Map.maxView@ from 'Map', this cannot ever fail,+-- so doesn't need to return in a 'Maybe'. However, the result 'Map' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > maxView (fromList ((5,"a") :| [(3,"b")])) == ("a", Data.Map.singleton 3 "b")+maxView :: NEMap k a -> (a, Map k a)+maxView = first snd . deleteFindMax+{-# INLINE maxView #-}++-- | /O(log n)/. Delete and find the minimal key-value pair.+--+-- Note that unlike @Data.Map.deleteFindMax@ for 'Map', this cannot ever+-- fail, and so is a total function. However, the result 'Map' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > deleteFindMax (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((10,"c"), Data.Map.fromList [(3,"b"), (5,"a")])+deleteFindMax :: NEMap k a -> ((k, a), Map k a)+deleteFindMax (NEMap k v m) =+ maybe ((k, v), M.empty) (second (insertMinMap k v))+ . M.maxViewWithKey+ $ m+{-# INLINE deleteFindMax #-}++-- | Special property of non-empty maps: The type of non-empty maps over+-- uninhabited keys is itself uninhabited.+--+-- This property also exists for /values/ inside a non-empty container+-- (like for 'NESet', 'NESeq', and 'NEIntMap'); this can be witnessed using+-- the function @'absurd' . 'fold1'@.+--+-- @since 0.3.1.0+absurdNEMap :: NEMap Void a -> b+absurdNEMap = \case {}++-- ---------------------------+-- Combining functions+-- ---------------------------+--+-- Code comes from "Data.Map.Internal" from containers, modified slightly+-- to work with NonEmpty+--+-- Copyright : (c) Daan Leijen 2002+-- (c) Andriy Palamarchuk 2008++combineEq :: Eq a => NonEmpty (a, b) -> NonEmpty (a, b)+combineEq = \case+ x :| [] -> x :| []+ x :| xx@(_ : _) -> go x xx+ where+ go z [] = z :| []+ go z@(kz, _) (x@(kx, xx) : xs')+ | kx == kz = go (kx, xx) xs'+ | otherwise = z NE.<| go x xs'++combineEqWith ::+ Eq a =>+ (a -> b -> b -> b) ->+ NonEmpty (a, b) ->+ NonEmpty (a, b)+combineEqWith f = \case+ x :| [] -> x :| []+ x :| xx@(_ : _) -> go x xx+ where+ go z [] = z :| []+ go z@(kz, zz) (x@(kx, xx) : xs')+ | kx == kz = let yy = f kx xx zz in go (kx, yy) xs'+ | otherwise = z NE.<| go x xs'
+ src/Data/Map/NonEmpty/Lazy/Internal.hs view
@@ -0,0 +1,726 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ViewPatterns #-}+{-# OPTIONS_HADDOCK not-home #-}++-- |+-- Module : Data.Map.NonEmpty.Lazy.Internal+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- Unsafe internal-use functions used in the implementation of+-- "Data.Map.NonEmpty.Lazy". These functions can potentially be used to break+-- the abstraction of 'NEMap' and produce unsound maps, so be wary!+module Data.Map.NonEmpty.Lazy.Internal (+ -- * Non-Empty Map type+ NEMap (..),+ singleton,+ nonEmptyMap,+ withNonEmpty,+ fromList,+ toList,+ map,+ insertWith,+ union,+ unions,+ elems,+ size,+ toMap,++ -- * Folds+ foldr,+ foldr',+ foldr1,+ foldl,+ foldl',+ foldl1,++ -- * Traversals+ traverseWithKey,+ traverseWithKey1,+ foldMapWithKey,++ -- * Unsafe Map Functions+ insertMinMap,+ insertMaxMap,++ -- * Debug+ valid,+) where++import Control.Applicative+import Control.Comonad+import Control.DeepSeq+import Control.Monad+import qualified Data.Aeson as A+import Data.Coerce+import Data.Data+import qualified Data.Foldable as F+import Data.Foldable.WithIndex (FoldableWithIndex (..))+import Data.Function+import Data.Functor.Alt+import Data.Functor.Classes+import Data.Functor.Invariant+import Data.Functor.WithIndex (FunctorWithIndex (..))+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.Map as M+import Data.Map.Internal (Map (..))+import qualified Data.Map.Internal as M+import Data.Maybe+import Data.Semigroup+import Data.Semigroup.Foldable (Foldable1 (fold1))+import qualified Data.Semigroup.Foldable as F1+import Data.Semigroup.Traversable (Traversable1 (..))+import Data.Traversable.WithIndex (TraversableWithIndex (..))+import qualified GHC.Exts as Exts+import Text.Read+import Prelude hiding (Foldable (..), map)++-- | A non-empty (by construction) map from keys @k@ to values @a@. At+-- least one key-value pair exists in an @'NEMap' k v@ at all times.+--+-- Functions that /take/ an 'NEMap' can safely operate on it with the+-- assumption that it has at least one key-value pair.+--+-- Functions that /return/ an 'NEMap' provide an assurance that the result+-- has at least one key-value pair.+--+-- "Data.Map.NonEmpty.Lazy" re-exports the API of "Data.Map.Lazy", faithfully+-- reproducing asymptotics, typeclass constraints, and semantics.+-- Functions that ensure that input and output maps are both non-empty+-- (like 'Data.Map.NonEmpty.Lazy.insert') return 'NEMap', but functions that+-- might potentially return an empty map (like 'Data.Map.NonEmpty.Lazy.delete')+-- return a 'Map' instead.+--+-- You can directly construct an 'NEMap' with the API from+-- "Data.Map.NonEmpty.Lazy"; it's more or less the same as constructing a normal+-- 'Map', except you don't have access to 'Data.Map.empty'. There are also+-- a few ways to construct an 'NEMap' from a 'Map':+--+-- 1. The 'nonEmptyMap' smart constructor will convert a @'Map' k a@ into+-- a @'Maybe' ('NEMap' k a)@, returning 'Nothing' if the original 'Map'+-- was empty.+-- 2. You can use the 'Data.Map.NonEmpty.insertMap' family of functions to+-- insert a value into a 'Map' to create a guaranteed 'NEMap'.+-- 3. You can use the 'Data.Map.NonEmpty.Lazy.IsNonEmpty' and+-- 'Data.Map.NonEmpty.Lazy.IsEmpty' patterns to "pattern match" on a 'Map'+-- to reveal it as either containing a 'NEMap' or an empty map.+-- 4. 'withNonEmpty' offers a continuation-based interface for+-- deconstructing a 'Map' and treating it as if it were an 'NEMap'.+--+-- You can convert an 'NEMap' into a 'Map' with 'toMap' or+-- 'Data.Map.NonEmpty.Lazy.IsNonEmpty', essentially "obscuring" the non-empty+-- property from the type.+data NEMap k a+ = NEMap+ { nemK0 :: !k+ -- ^ invariant: must be smaller than smallest key in map+ , nemV0 :: a+ , nemMap :: !(Map k a)+ }+ deriving (Typeable)++instance (Eq k, Eq a) => Eq (NEMap k a) where+ t1 == t2 =+ M.size (nemMap t1) == M.size (nemMap t2)+ && toList t1 == toList t2++instance (Ord k, Ord a) => Ord (NEMap k a) where+ compare = compare `on` toList+ (<) = (<) `on` toList+ (>) = (>) `on` toList+ (<=) = (<=) `on` toList+ (>=) = (>=) `on` toList++instance Eq2 NEMap where+ liftEq2 eqk eqv m n =+ size m == size n && liftEq (liftEq2 eqk eqv) (toList m) (toList n)++instance Eq k => Eq1 (NEMap k) where+ liftEq = liftEq2 (==)++instance Ord2 NEMap where+ liftCompare2 cmpk cmpv m n =+ liftCompare (liftCompare2 cmpk cmpv) (toList m) (toList n)++instance Ord k => Ord1 (NEMap k) where+ liftCompare = liftCompare2 compare++instance Show2 NEMap where+ liftShowsPrec2 spk slk spv slv d m =+ showsUnaryWith (liftShowsPrec sp sl) "fromList" d (toList m)+ where+ sp = liftShowsPrec2 spk slk spv slv+ sl = liftShowList2 spk slk spv slv++instance Show k => Show1 (NEMap k) where+ liftShowsPrec = liftShowsPrec2 showsPrec showList++instance (Ord k, Read k) => Read1 (NEMap k) where+ liftReadsPrec rp rl =+ readsData $+ readsUnaryWith (liftReadsPrec rp' rl') "fromList" fromList+ where+ rp' = liftReadsPrec rp rl+ rl' = liftReadList rp rl++instance (Ord k, Read k, Read e) => Read (NEMap k e) where+ readPrec = parens $ prec 10 $ do+ Ident "fromList" <- lexP+ xs <- parens . prec 10 $ readPrec+ return (fromList xs)+ readListPrec = readListPrecDefault++instance (Show k, Show a) => Show (NEMap k a) where+ showsPrec d m =+ showParen (d > 10) $+ showString "fromList (" . shows (toList m) . showString ")"++instance (NFData k, NFData a) => NFData (NEMap k a) where+ rnf (NEMap k v a) = rnf k `seq` rnf v `seq` rnf a++-- | @since 0.3.6.0+instance FunctorWithIndex k (NEMap k) where+ imap f (NEMap k v m) = NEMap k (f k v) (M.mapWithKey f m)++-- | @since 0.3.6.0+instance FoldableWithIndex k (NEMap k) where+ ifoldMap = foldMapWithKey++-- | @since 0.3.6.0+instance TraversableWithIndex k (NEMap k) where+ itraverse f (NEMap k v m) = NEMap k <$> f k v <*> M.traverseWithKey f m++-- | @since 0.3.6.0+instance Ord k => Exts.IsList (NEMap k a) where+ type Item (NEMap k a) = (k, a)++ fromList (a : as) = fromList (a :| as)+ fromList [] = errorWithoutStackTrace "Data.Map.NonEmpty.fromList: empty list"++ toList = F.toList . toList++-- Data instance code from Data.Map.Internal+--+-- Copyright : (c) Daan Leijen 2002+-- (c) Andriy Palamarchuk 2008+#if MIN_VERSION_base(4,16,0)+instance (Data k, Data a, Ord k) => Data (NEMap k a) where+ gfoldl f z m = z fromList `f` toList m+ toConstr _ = fromListConstr+ gunfold k z c = case constrIndex c of+ 1 -> k (z fromList)+ _ -> error "gunfold"+ dataTypeOf _ = mapDataType+ dataCast2 = gcast2+#else+#ifndef __HLINT__+instance (Data k, Data a, Ord k) => Data (NEMap k a) where+ gfoldl f z m = z fromList `f` toList m+ toConstr _ = fromListConstr+ gunfold k z c = case constrIndex c of+ 1 -> k (z fromList)+ _ -> error "gunfold"+ dataTypeOf _ = mapDataType+ dataCast2 f = gcast2 f+#endif+#endif++fromListConstr :: Constr+fromListConstr = mkConstr mapDataType "fromList" [] Prefix++mapDataType :: DataType+mapDataType = mkDataType "Data.Map.NonEmpty.NonEmpty.Internal.NEMap" [fromListConstr]++instance (A.ToJSONKey k, A.ToJSON a) => A.ToJSON (NEMap k a) where+ toJSON = A.toJSON . toMap+ toEncoding = A.toEncoding . toMap++instance (A.FromJSONKey k, Ord k, A.FromJSON a) => A.FromJSON (NEMap k a) where+ parseJSON =+ withNonEmpty (fail err) pure+ <=< A.parseJSON+ where+ err = "NEMap: Non-empty map expected, but empty map found"++-- | @since 0.3.4.4+instance Ord k => Alt (NEMap k) where+ (<!>) = union+ {-# INLINE (<!>) #-}++-- | /O(n)/. Fold the values in the map using the given right-associative+-- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'elems'@.+--+-- > elemsList map = foldr (:) [] map+--+-- > let f a len = len + (length a)+-- > foldr f 0 (fromList ((5,"a") :| [(3,"bbb")])) == 4+foldr :: (a -> b -> b) -> b -> NEMap k a -> b+foldr f z (NEMap _ v m) = v `f` M.foldr f z m+{-# INLINE foldr #-}++-- | /O(n)/. A strict version of 'foldr'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldr' :: (a -> b -> b) -> b -> NEMap k a -> b+foldr' f z (NEMap _ v m) = v `f` y+ where+ !y = M.foldr' f z m+{-# INLINE foldr' #-}++-- | /O(n)/. A version of 'foldr' that uses the value at the maximal key in+-- the map as the starting value.+--+-- Note that, unlike 'Data.Foldable.foldr1' for 'Map', this function is+-- total if the input function is total.+foldr1 :: (a -> a -> a) -> NEMap k a -> a+foldr1 f (NEMap _ v m) =+ maybe v (f v . uncurry (M.foldr f))+ . M.maxView+ $ m+{-# INLINE foldr1 #-}++-- | /O(n)/. Fold the values in the map using the given left-associative+-- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'elems'@.+--+-- > elemsList = reverse . foldl (flip (:)) []+--+-- > let f len a = len + (length a)+-- > foldl f 0 (fromList ((5,"a") :| [(3,"bbb")])) == 4+foldl :: (a -> b -> a) -> a -> NEMap k b -> a+foldl f z (NEMap _ v m) = M.foldl f (f z v) m+{-# INLINE foldl #-}++-- | /O(n)/. A strict version of 'foldl'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldl' :: (a -> b -> a) -> a -> NEMap k b -> a+foldl' f z (NEMap _ v m) = M.foldl' f x m+ where+ !x = f z v+{-# INLINE foldl' #-}++-- | /O(n)/. A version of 'foldl' that uses the value at the minimal key in+-- the map as the starting value.+--+-- Note that, unlike 'Data.Foldable.foldl1' for 'Map', this function is+-- total if the input function is total.+foldl1 :: (a -> a -> a) -> NEMap k a -> a+foldl1 f (NEMap _ v m) = M.foldl f v m+{-# INLINE foldl1 #-}++-- | /O(n)/. Fold the keys and values in the map using the given semigroup,+-- such that+--+-- @'foldMapWithKey' f = 'Data.Semigroup.Foldable.fold1' . 'Data.Map.NonEmpty.mapWithKey' f@+--+-- This can be an asymptotically faster than+-- 'Data.Map.NonEmpty.foldrWithKey' or 'Data.Map.NonEmpty.foldlWithKey' for+-- some monoids.++-- TODO: benchmark against maxView method+foldMapWithKey ::+ Semigroup m =>+ (k -> a -> m) ->+ NEMap k a ->+ m+#if MIN_VERSION_base(4,11,0)+foldMapWithKey f (NEMap k0 v m) = maybe (f k0 v) (f k0 v <>)+ . M.foldMapWithKey (\k -> Just . f k)+ $ m+#else+foldMapWithKey f (NEMap k0 v m) = option (f k0 v) (f k0 v <>)+ . M.foldMapWithKey (\k -> Option . Just . f k)+ $ m+#endif+{-# INLINE foldMapWithKey #-}++-- | /O(n)/. Map a function over all values in the map.+--+-- > map (++ "x") (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "bx") :| [(5, "ax")])+map :: (a -> b) -> NEMap k a -> NEMap k b+map f (NEMap k0 v m) = NEMap k0 (f v) (M.map f m)+{-# NOINLINE [1] map #-}++{-# RULES+"map/map" forall f g xs. map f (map g xs) = map (f . g) xs+ #-}+{-# RULES+"map/coerce" map coerce = coerce+ #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- 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' == 'Data.Map.NonEmpty.unionWith' 'const'@).+--+-- > union (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "a"), (7, "C")])+union ::+ Ord k =>+ NEMap k a ->+ NEMap k a ->+ NEMap k a+union n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEMap k1 v1 . M.union m1 . toMap $ n2+ EQ -> NEMap k1 v1 . M.union m1 $ m2+ GT -> NEMap k2 v2 . M.union (toMap n1) $ m2+{-# INLINE union #-}++-- | The left-biased union of a non-empty list of maps.+--+-- > unions (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])+-- > == fromList [(3, "b"), (5, "a"), (7, "C")]+-- > unions (fromList ((5, "A3") :| [(3, "B3")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "a") :| [(3, "b")])])+-- > == fromList ((3, "B3") :| [(5, "A3"), (7, "C")])+unions ::+ (Foldable1 f, Ord k) =>+ f (NEMap k a) ->+ NEMap k a+unions (F1.toNonEmpty -> (m :| ms)) = F.foldl' union m ms+{-# INLINE unions #-}++-- | /O(n)/.+-- Return all elements of the map in the ascending order of their keys.+--+-- > elems (fromList ((5,"a") :| [(3,"b")])) == ("b" :| ["a"])+elems :: NEMap k a -> NonEmpty a+elems (NEMap _ v m) = v :| M.elems m+{-# INLINE elems #-}++-- | /O(1)/. The number of elements in the map. Guaranteed to be greater+-- than zero.+--+-- > size (singleton 1 'a') == 1+-- > size (fromList ((1,'a') :| [(2,'c'), (3,'b')])) == 3+size :: NEMap k a -> Int+size (NEMap _ _ m) = 1 + M.size m+{-# INLINE size #-}++-- | /O(log n)/.+-- Convert a non-empty map back into a normal possibly-empty map, for usage+-- with functions that expect 'Map'.+--+-- Can be thought of as "obscuring" the non-emptiness of the map in its+-- type. See the 'Data.Map.NonEmpty.IsNotEmpty' pattern.+--+-- 'nonEmptyMap' and @'maybe' 'Data.Map.empty' 'toMap'@ form an isomorphism: they+-- are perfect structure-preserving inverses of eachother.+--+-- > toMap (fromList ((3,"a") :| [(5,"b")])) == Data.Map.fromList [(3,"a"), (5,"b")]+toMap :: NEMap k a -> Map k a+toMap (NEMap k v m) = insertMinMap k v m+{-# INLINE toMap #-}++-- | /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.+--+-- /Use 'traverseWithKey1'/ whenever possible (if your 'Applicative'+-- also has 'Apply' instance). This version is provided only for types+-- that do not have 'Apply' instance, since 'Apply' is not at the moment+-- (and might not ever be) an official superclass of 'Applicative'.+--+-- @+-- 'traverseWithKey' f = 'unwrapApplicative' . 'traverseWithKey1' (\\k -> WrapApplicative . f k)+-- @+traverseWithKey ::+ Applicative t =>+ (k -> a -> t b) ->+ NEMap k a ->+ t (NEMap k b)+traverseWithKey f (NEMap k v m0) = NEMap k <$> f k v <*> M.traverseWithKey f m0+{-# INLINE traverseWithKey #-}++-- | /O(n)/.+-- @'traverseWithKey1' f m == 'fromList' <$> 'traverse1' (\(k, v) -> (,) k <$> f k v) ('toList' m)@+--+-- That is, behaves exactly like a regular 'traverse1' except that the traversing+-- function also has access to the key associated with a value.+--+-- Is more general than 'traverseWithKey', since works with all 'Apply',+-- and not just 'Applicative'.++-- TODO: benchmark against maxView-based methods+traverseWithKey1 ::+ Apply t =>+ (k -> a -> t b) ->+ NEMap k a ->+ t (NEMap k b)+traverseWithKey1 f (NEMap k0 v m0) = case runMaybeApply m1 of+ Left m2 -> NEMap k0 <$> f k0 v <.> m2+ Right m2 -> flip (NEMap k0) m2 <$> f k0 v+ where+ m1 = M.traverseWithKey (\k -> MaybeApply . Left . f k) m0+{-# INLINEABLE traverseWithKey1 #-}++-- | /O(n)/. Convert the map to a non-empty list of key\/value pairs.+--+-- > toList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+toList :: NEMap k a -> NonEmpty (k, a)+toList (NEMap k v m) = (k, v) :| M.toList m+{-# INLINE toList #-}++-- | /O(log n)/. Smart constructor for an 'NEMap' from a 'Map'. Returns+-- 'Nothing' if the 'Map' was originally actually empty, and @'Just' n@+-- with an 'NEMap', if the 'Map' was not empty.+--+-- 'nonEmptyMap' and @'maybe' 'Data.Map.empty' 'toMap'@ form an+-- isomorphism: they are perfect structure-preserving inverses of+-- eachother.+--+-- See 'Data.Map.NonEmpty.IsNonEmpty' for a pattern synonym that lets you+-- "match on" the possiblity of a 'Map' being an 'NEMap'.+--+-- > nonEmptyMap (Data.Map.fromList [(3,"a"), (5,"b")]) == Just (fromList ((3,"a") :| [(5,"b")]))+nonEmptyMap :: Map k a -> Maybe (NEMap k a)+nonEmptyMap = (fmap . uncurry . uncurry) NEMap . M.minViewWithKey+{-# INLINE nonEmptyMap #-}++-- | /O(log n)/. A general continuation-based way to consume a 'Map' as if+-- it were an 'NEMap'. @'withNonEmpty' def f@ will take a 'Map'. If map is+-- empty, it will evaluate to @def@. Otherwise, a non-empty map 'NEMap'+-- will be fed to the function @f@ instead.+--+-- @'nonEmptyMap' == 'withNonEmpty' 'Nothing' 'Just'@+withNonEmpty ::+ -- | value to return if map is empty+ r ->+ -- | function to apply if map is not empty+ (NEMap k a -> r) ->+ Map k a ->+ r+withNonEmpty def f = maybe def f . nonEmptyMap+{-# INLINE withNonEmpty #-}++-- | /O(n*log n)/. Build a non-empty map from a non-empty list of+-- key\/value pairs. See also 'Data.Map.NonEmpty.fromAscList'. If the list+-- contains more than one value for the same key, the last value for the+-- key is retained.+--+-- > fromList ((5,"a") :| [(3,"b"), (5, "c")]) == fromList ((5,"c") :| [(3,"b")])+-- > fromList ((5,"c") :| [(3,"b"), (5, "a")]) == fromList ((5,"a") :| [(3,"b")])++-- TODO: write manually and optimize to be equivalent to+-- 'fromDistinctAscList' if items are ordered, just like the actual+-- 'M.fromList'.+fromList :: Ord k => NonEmpty (k, a) -> NEMap k a+fromList ((k, v) :| xs) =+ withNonEmpty (singleton k v) (insertWith (const id) k v)+ . M.fromList+ $ xs+{-# INLINE fromList #-}++-- | /O(1)/. A map with a single element.+--+-- > singleton 1 'a' == fromList ((1, 'a') :| [])+-- > size (singleton 1 'a') == 1+singleton :: k -> a -> NEMap k a+singleton k v = NEMap k v M.empty+{-# INLINE singleton #-}++-- | /O(log n)/. Insert with a function, combining new value and old value.+-- @'insertWith' f key value mp@ will insert the pair (key, value) into+-- @mp@ if key does not exist in the map. If the key does exist, the+-- function will insert the pair @(key, f new_value old_value)@.+--+-- See 'Data.Map.NonEmpty.insertMapWith' for a version where the first+-- argument is a 'Map'.+--+-- > insertWith (++) 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "xxxa")])+-- > insertWith (++) 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+insertWith ::+ Ord k =>+ (a -> a -> a) ->+ k ->+ a ->+ NEMap k a ->+ NEMap k a+insertWith f k v n@(NEMap k0 v0 m) = case compare k k0 of+ LT -> NEMap k v . toMap $ n+ EQ -> NEMap k (f v v0) m+ GT -> NEMap k0 v0 $ M.insertWith f k v m+{-# INLINE insertWith #-}++-- | Left-biased union+instance Ord k => Semigroup (NEMap k a) where+ (<>) = union+ {-# INLINE (<>) #-}+ sconcat = unions+ {-# INLINE sconcat #-}++instance Functor (NEMap k) where+ fmap = map+ {-# INLINE fmap #-}+ x <$ NEMap k _ m = NEMap k x (x <$ m)+ {-# INLINE (<$) #-}++-- | @since 0.3.4.4+instance Invariant (NEMap k) where+ invmap f _ = fmap f+ {-# INLINE invmap #-}++-- | Traverses elements in order of ascending keys+--+-- 'Data.Foldable.foldr1', 'Data.Foldable.foldl1', 'Data.Foldable.minimum',+-- 'Data.Foldable.maximum' are all total.+#if MIN_VERSION_base(4,11,0)+instance F.Foldable (NEMap k) where+ fold (NEMap _ v m) = v <> F.fold m+ {-# INLINE fold #-}+ foldMap f (NEMap _ v m) = f v <> F.foldMap f m+ {-# INLINE foldMap #-}+ foldr = foldr+ {-# INLINE foldr #-}+ foldr' = foldr'+ {-# INLINE foldr' #-}+ foldr1 = foldr1+ {-# INLINE foldr1 #-}+ foldl = foldl+ {-# INLINE foldl #-}+ foldl' = foldl'+ {-# INLINE foldl' #-}+ foldl1 = foldl1+ {-# INLINE foldl1 #-}+ null _ = False+ {-# INLINE null #-}+ length = size+ {-# INLINE length #-}+ elem x (NEMap _ v m) = F.elem x m+ || x == v+ {-# INLINE elem #-}+ -- TODO: use build+ toList = F.toList . elems+ {-# INLINE toList #-}+#else+instance F.Foldable (NEMap k) where+ fold (NEMap _ v m) = v `mappend` F.fold m+ {-# INLINE fold #-}+ foldMap f (NEMap _ v m) = f v `mappend` F.foldMap f m+ {-# INLINE foldMap #-}+ foldr = foldr+ {-# INLINE foldr #-}+ foldr' = foldr'+ {-# INLINE foldr' #-}+ foldr1 = foldr1+ {-# INLINE foldr1 #-}+ foldl = foldl+ {-# INLINE foldl #-}+ foldl' = foldl'+ {-# INLINE foldl' #-}+ foldl1 = foldl1+ {-# INLINE foldl1 #-}+ null _ = False+ {-# INLINE null #-}+ length = size+ {-# INLINE length #-}+ elem x (NEMap _ v m) = F.elem x m+ || x == v+ {-# INLINE elem #-}+ -- TODO: use build+ toList = F.toList . elems+ {-# INLINE toList #-}+#endif++-- | Traverses elements in order of ascending keys+instance Traversable (NEMap k) where+ traverse f (NEMap k v m) = NEMap k <$> f v <*> traverse f m+ {-# INLINE traverse #-}+ sequenceA (NEMap k v m) = NEMap k <$> v <*> sequenceA m+ {-# INLINE sequenceA #-}++-- | Traverses elements in order of ascending keys+#if MIN_VERSION_base(4,11,0)+instance Foldable1 (NEMap k) where+ fold1 (NEMap _ v m) = maybe v (v <>)+ . F.foldMap Just+ $ m+ {-# INLINE fold1 #-}+ foldMap1 f = foldMapWithKey (const f)+ {-# INLINE foldMap1 #-}+ toNonEmpty = elems+ {-# INLINE toNonEmpty #-}+#else+instance Foldable1 (NEMap k) where+ fold1 (NEMap _ v m) = option v (v <>)+ . F.foldMap (Option . Just)+ $ m+ {-# INLINE fold1 #-}+ foldMap1 f = foldMapWithKey (const f)+ {-# INLINE foldMap1 #-}+ toNonEmpty = elems+ {-# INLINE toNonEmpty #-}+#endif++-- | Traverses elements in order of ascending keys+instance Traversable1 (NEMap k) where+ traverse1 f = traverseWithKey1 (const f)+ {-# INLINE traverse1 #-}+ sequence1 (NEMap k v m0) = case runMaybeApply m1 of+ Left m2 -> NEMap k <$> v <.> m2+ Right m2 -> flip (NEMap k) m2 <$> v+ where+ m1 = traverse (MaybeApply . Left) m0+ {-# INLINEABLE sequence1 #-}++-- | 'extract' gets the value at the minimal key, and 'duplicate' produces+-- a map of maps comprised of all keys from the original map greater than+-- or equal to the current key.+--+-- @since 0.1.1.0+instance Comonad (NEMap k) where+ extract = nemV0+ {-# INLINE extract #-}+ duplicate n0@(NEMap k0 _ m0) =+ NEMap k0 n0+ . snd+ . M.mapAccumWithKey go m0+ $ m0+ where+ go m k v = (m', NEMap k v m')+ where+ !m' = M.deleteMin m+ {-# INLINE duplicate #-}++-- | /O(n)/. Test if the internal map structure is valid.+valid :: Ord k => NEMap k a -> Bool+valid (NEMap k _ m) =+ M.valid m+ && all ((k <) . fst . fst) (M.minViewWithKey m)++-- | /O(log n)/. Insert new key and value into a map where keys are+-- /strictly greater than/ the new key. That is, the new key must be+-- /strictly less than/ all keys present in the 'Map'. /The precondition+-- is not checked./+--+-- While this has the same asymptotics as @Data.Map.insert@, it saves+-- a constant factor for key comparison (so may be helpful if comparison is+-- expensive) and also does not require an 'Ord' instance for the key type.+insertMinMap :: k -> a -> Map k a -> Map k a+insertMinMap kx x = \case+ Tip -> M.singleton kx x+ Bin _ ky y l r -> M.balanceL ky y (insertMinMap kx x l) r+{-# INLINEABLE insertMinMap #-}++-- | /O(log n)/. Insert new key and value into a map where keys are+-- /strictly less than/ the new key. That is, the new key must be+-- /strictly greater than/ all keys present in the 'Map'. /The+-- precondition is not checked./+--+-- While this has the same asymptotics as @Data.Map.insert@, it saves+-- a constant factor for key comparison (so may be helpful if comparison is+-- expensive) and also does not require an 'Ord' instance for the key type.+insertMaxMap :: k -> a -> Map k a -> Map k a+insertMaxMap kx x = \case+ Tip -> M.singleton kx x+ Bin _ ky y l r -> M.balanceR ky y l (insertMaxMap kx x r)+{-# INLINEABLE insertMaxMap #-}
+ src/Data/Map/NonEmpty/Strict.hs view
@@ -0,0 +1,2492 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE EmptyCase #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ViewPatterns #-}++-- |+-- Module : Data.Map.NonEmpty.Strict+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- = Non-Empty Finite Maps (strict interface)+--+-- The @'NEMap' k v@ type represents a non-empty finite map (sometimes+-- called a dictionary) from keys of type @k@ to values of type @v@.+-- An 'NEMap' is strict in its keys and values.+--+-- See documentation for 'NEMap' for information on how to convert and+-- manipulate such non-empty maps.+--+-- This module essentially re-imports the API of "Data.Map.Strict" and its+-- 'Map' type, along with semantics and asymptotics. In most situations,+-- asymptotics are different only by a constant factor. In some+-- situations, asmyptotics are even better (constant-time instead of+-- log-time). All typeclass constraints are identical to their "Data.Map"+-- counterparts.+--+-- Because 'NEMap' is implemented using 'Map', all of the caveats of using+-- 'Map' apply (such as the limitation of the maximum size of maps).+--+-- All functions take non-empty maps as inputs. In situations where their+-- results can be guarunteed to also be non-empty, they also return+-- non-empty maps. In situations where their results could potentially be+-- empty, 'Map' is returned instead.+--+-- Some variants of functions (like 'alter'', 'alterF'', 'adjustAt',+-- 'adjustMin', 'adjustMax', 'adjustMinWithKey', 'adjustMaxWithKey') are+-- provided in a way restructured to preserve guaruntees of non-empty maps+-- being returned.+--+-- Some functions (like 'mapEither', 'partition', 'spanAntitone', 'split')+-- have modified return types to account for possible configurations of+-- non-emptiness.+--+-- This module is intended to be imported qualified, to avoid name clashes with+-- "Prelude" and "Data.Map" functions:+--+-- > import qualified Data.Map.NonEmpty.Strict as NEM+--+-- Import "Data.Map.NonEmpty.Lazy" for a variant lazy in values.+module Data.Map.NonEmpty.Strict (+ -- * Non-Empty Map type+ NEMap,++ -- ** Conversions between empty and non-empty maps+ pattern IsNonEmpty,+ pattern IsEmpty,+ nonEmptyMap,+ toMap,+ withNonEmpty,+ insertMap,+ insertMapWith,+ insertMapWithKey,+ insertMapMin,+ insertMapMax,+ unsafeFromMap,++ -- * Construction+ singleton,+ fromSet,++ -- ** From Unordered Lists+ fromList,+ fromListWith,+ fromListWithKey,++ -- ** From Ascending Lists+ fromAscList,+ fromAscListWith,+ fromAscListWithKey,+ fromDistinctAscList,++ -- ** From Descending Lists+ fromDescList,+ fromDescListWith,+ fromDescListWithKey,+ fromDistinctDescList,++ -- * Insertion+ insert,+ insertWith,+ insertWithKey,+ insertLookupWithKey,++ -- * Deletion\/Update+ delete,+ deleteMaybe,+ adjust,+ adjustWithKey,+ update,+ updateWithKey,+ updateLookupWithKey,+ alter,+ alterF,+ alter',+ alterF',++ -- * Query++ -- ** Lookup+ lookup,+ (!?),+ (!),+ findWithDefault,+ member,+ notMember,+ lookupLT,+ lookupGT,+ lookupLE,+ lookupGE,+ absurdNEMap,++ -- ** Size+ size,++ -- * Combine++ -- ** Union+ union,+ unionMapLeft,+ unionMapRight,+ unionWith,+ unionMapWithLeft,+ unionMapWithRight,+ unionWithKey,+ unionMapWithKeyLeft,+ unionMapWithKeyRight,+ unions,+ unionsWith,++ -- ** Difference+ difference,+ (\\),+ differenceWith,+ differenceWithKey,++ -- ** Intersection+ intersection,+ intersectionWith,+ intersectionWithKey,+ -- -- ** Unsafe general combining function+ -- , mergeWithKey++ -- * Traversal++ -- ** Map+ map,+ mapWithKey,+ traverseWithKey1,+ traverseWithKey,+ traverseMaybeWithKey1,+ traverseMaybeWithKey,+ mapAccum,+ mapAccumWithKey,+ mapAccumRWithKey,+ mapKeys,+ mapKeysWith,+ mapKeysMonotonic,++ -- * Folds+ foldr,+ foldl,+ foldr1,+ foldl1,+ foldrWithKey,+ foldlWithKey,+ foldMapWithKey,++ -- ** Strict folds+ foldr',+ foldr1',+ foldl',+ foldl1',+ foldrWithKey',+ foldlWithKey',++ -- * Conversion+ elems,+ keys,+ assocs,+ keysSet,++ -- ** Lists+ toList,++ -- ** Ordered lists+ toAscList,+ toDescList,++ -- * Filter+ filter,+ filterWithKey,+ restrictKeys,+ withoutKeys,+ partition,+ partitionWithKey,+ takeWhileAntitone,+ dropWhileAntitone,+ spanAntitone,+ mapMaybe,+ mapMaybeWithKey,+ mapEither,+ mapEitherWithKey,+ split,+ splitLookup,+ splitRoot,++ -- * Submap+ isSubmapOf,+ isSubmapOfBy,+ isProperSubmapOf,+ isProperSubmapOfBy,++ -- * Indexed+ lookupIndex,+ findIndex,+ elemAt,+ updateAt,+ adjustAt,+ deleteAt,+ take,+ drop,+ splitAt,++ -- * Min\/Max+ findMin,+ findMax,+ deleteMin,+ deleteMax,+ deleteFindMin,+ deleteFindMax,+ updateMin,+ updateMax,+ adjustMin,+ adjustMax,+ updateMinWithKey,+ updateMaxWithKey,+ adjustMinWithKey,+ adjustMaxWithKey,+ minView,+ maxView,++ -- * Debugging+ valid,+) where++import Control.Applicative+import Data.Bifunctor+import qualified Data.Foldable as F+import Data.Function+import Data.Functor.Apply+import Data.Functor.Identity+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE+import Data.Map (Map)+import Data.Map.NonEmpty.Strict.Internal+import qualified Data.Map.Strict as M+import Data.Maybe hiding (mapMaybe)+import qualified Data.Maybe as Maybe+import Data.Semigroup.Foldable (Foldable1)+import qualified Data.Semigroup.Foldable as F1+import Data.Set (Set)+import qualified Data.Set as S+import Data.Set.NonEmpty.Internal (NESet (..))+import Data.These+import Data.Void+import Prelude hiding (Foldable (..), drop, filter, lookup, map, splitAt, take)++-- | /O(1)/ match, /O(log n)/ usage of contents. The 'IsNonEmpty' and+-- 'IsEmpty' patterns allow you to treat a 'Map' as if it were either+-- a @'IsNonEmpty' n@ (where @n@ is a 'NEMap') or an 'IsEmpty'.+--+-- For example, you can pattern match on a 'Map':+--+-- @+-- myFunc :: 'Map' K X -> Y+-- myFunc ('IsNonEmpty' n) = -- here, the user provided a non-empty map, and @n@ is the 'NEMap'+-- myFunc 'IsEmpty' = -- here, the user provided an empty map.+-- @+--+-- Matching on @'IsNonEmpty' n@ means that the original 'Map' was /not/+-- empty, and you have a verified-non-empty 'NEMap' @n@ to use.+--+-- Note that patching on this pattern is /O(1)/. However, using the+-- contents requires a /O(log n)/ cost that is deferred until after the+-- pattern is matched on (and is not incurred at all if the contents are+-- never used).+--+-- A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides+-- complete coverage.+--+-- This is a bidirectional pattern, so you can use 'IsNonEmpty' to convert+-- a 'NEMap' back into a 'Map', obscuring its non-emptiness (see 'toMap').+pattern IsNonEmpty :: NEMap k a -> Map k a+pattern IsNonEmpty n <- (nonEmptyMap -> Just n)+ where+ IsNonEmpty n = toMap n++-- | /O(1)/. The 'IsNonEmpty' and 'IsEmpty' patterns allow you to treat+-- a 'Map' as if it were either a @'IsNonEmpty' n@ (where @n@ is+-- a 'NEMap') or an 'IsEmpty'.+--+-- Matching on 'IsEmpty' means that the original 'Map' was empty.+--+-- A case statement handling both 'IsNonEmpty' and 'IsEmpty' provides+-- complete coverage.+--+-- This is a bidirectional pattern, so you can use 'IsEmpty' as an+-- expression, and it will be interpreted as 'Data.Map.empty'.+--+-- See 'IsNonEmpty' for more information.+pattern IsEmpty :: Map k a+pattern IsEmpty <- (M.null -> True)+ where+ IsEmpty = M.empty++{-# COMPLETE IsNonEmpty, IsEmpty #-}++-- | /O(log n)/. Unsafe version of 'nonEmptyMap'. Coerces a 'Map' into an+-- 'NEMap', but is undefined (throws a runtime exception when evaluation is+-- attempted) for an empty 'Map'.+unsafeFromMap ::+ Map k a ->+ NEMap k a+unsafeFromMap = withNonEmpty e id+ where+ e = errorWithoutStackTrace "NEMap.unsafeFromMap: empty map"+{-# INLINE unsafeFromMap #-}++-- | /O(n)/. Build a non-empty map from a non-empty set of keys and+-- a function which for each key computes its value.+--+-- > fromSet (\k -> replicate k 'a') (Data.Set.NonEmpty.fromList (3 :| [5])) == fromList ((5,"aaaaa") :| [(3,"aaa")])+fromSet ::+ (k -> a) ->+ NESet k ->+ NEMap k a+fromSet f (NESet k ks) = NEMap k (f k) (M.fromSet f ks)+{-# INLINE fromSet #-}++-- | /O(log n)/. Lookup the value at a key in the map.+--+-- The function will return the corresponding value as @('Just' value)@,+-- or 'Nothing' if the key isn't in the map.+--+-- An example of using @lookup@:+--+-- > import Prelude hiding (lookup)+-- > import Data.Map.NonEmpty+-- >+-- > employeeDept = fromList (("John","Sales") :| [("Bob","IT")])+-- > deptCountry = fromList (("IT","USA") :| [("Sales","France")])+-- > countryCurrency = fromList (("USA", "Dollar") :| [("France", "Euro")])+-- >+-- > employeeCurrency :: String -> Maybe String+-- > employeeCurrency name = do+-- > dept <- lookup name employeeDept+-- > country <- lookup dept deptCountry+-- > lookup country countryCurrency+-- >+-- > main = do+-- > putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))+-- > putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))+--+-- The output of this program:+--+-- > John's currency: Just "Euro"+-- > Pete's currency: Nothing+lookup ::+ Ord k =>+ k ->+ NEMap k a ->+ Maybe a+lookup k (NEMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just v+ GT -> M.lookup k m+{-# INLINE lookup #-}++-- | /O(log n)/. Find the value at a key. Returns 'Nothing' when the+-- element can not be found.+--+-- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 1 == Nothing+-- prop> fromList ((5, 'a') :| [(3, 'b')]) !? 5 == Just 'a'+(!?) :: Ord k => NEMap k a -> k -> Maybe a+(!?) = flip lookup+{-# INLINE (!?) #-}++-- | /O(log n)/. Find the value at a key. Calls 'error' when the element+-- can not be found.+--+-- > fromList ((5,'a') :| [(3,'b')]) ! 1 Error: element not in the map+-- > fromList ((5,'a') :| [(3,'b')]) ! 5 == 'a'+(!) :: Ord k => NEMap k a -> k -> a+(!) m k = fromMaybe e $ m !? k+ where+ e = error "NEMap.!: given key is not an element in the map"+{-# INLINE (!) #-}++infixl 9 !?+infixl 9 !++-- | /O(log n)/. The expression @('findWithDefault' def k map)@ returns+-- the value at key @k@ or returns default value @def@+-- when the key is not in the map.+--+-- > findWithDefault 'x' 1 (fromList ((5,'a') :| [(3,'b')])) == 'x'+-- > findWithDefault 'x' 5 (fromList ((5,'a') :| [(3,'b')])) == 'a'+findWithDefault ::+ Ord k =>+ a ->+ k ->+ NEMap k a ->+ a+findWithDefault def k (NEMap k0 v m) = case compare k k0 of+ LT -> def+ EQ -> v+ GT -> M.findWithDefault def k m+{-# INLINE findWithDefault #-}++-- | /O(log n)/. Is the key a member of the map? See also 'notMember'.+--+-- > member 5 (fromList ((5,'a') :| [(3,'b')])) == True+-- > member 1 (fromList ((5,'a') :| [(3,'b')])) == False+member :: Ord k => k -> NEMap k a -> Bool+member k (NEMap k0 _ m) = case compare k k0 of+ LT -> False+ EQ -> True+ GT -> M.member k m+{-# INLINE member #-}++-- | /O(log n)/. Is the key not a member of the map? See also 'member'.+--+-- > notMember 5 (fromList ((5,'a') :| [(3,'b')])) == False+-- > notMember 1 (fromList ((5,'a') :| [(3,'b')])) == True+notMember :: Ord k => k -> NEMap k a -> Bool+notMember k (NEMap k0 _ m) = case compare k k0 of+ LT -> True+ EQ -> False+ GT -> M.notMember k m+{-# INLINE notMember #-}++-- | /O(log n)/. Find largest key smaller than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupLT 3 (fromList ((3,'a') :| [(5,'b')])) == Nothing+-- > lookupLT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+lookupLT :: Ord k => k -> NEMap k a -> Maybe (k, a)+lookupLT k (NEMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Nothing+ GT -> M.lookupLT k m <|> Just (k0, v)+{-# INLINE lookupLT #-}++-- | /O(log n)/. Find smallest key greater than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupGT 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+-- > lookupGT 5 (fromList ((3,'a') :| [(5,'b')])) == Nothing+lookupGT :: Ord k => k -> NEMap k a -> Maybe (k, a)+lookupGT k (NEMap k0 v m) = case compare k k0 of+ LT -> Just (k0, v)+ EQ -> M.lookupMin m+ GT -> M.lookupGT k m+{-# INLINE lookupGT #-}++-- | /O(log n)/. Find largest key smaller or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupLE 2 (fromList ((3,'a') :| [(5,'b')])) == Nothing+-- > lookupLE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+-- > lookupLE 5 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+lookupLE :: Ord k => k -> NEMap k a -> Maybe (k, a)+lookupLE k (NEMap k0 v m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just (k0, v)+ GT -> M.lookupLE k m <|> Just (k0, v)+{-# INLINE lookupLE #-}++-- | /O(log n)/. Find smallest key greater or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupGE 3 (fromList ((3,'a') :| [(5,'b')])) == Just (3, 'a')+-- > lookupGE 4 (fromList ((3,'a') :| [(5,'b')])) == Just (5, 'b')+-- > lookupGE 6 (fromList ((3,'a') :| [(5,'b')])) == Nothing+lookupGE :: Ord k => k -> NEMap k a -> Maybe (k, a)+lookupGE k (NEMap k0 v m) = case compare k k0 of+ LT -> Just (k0, v)+ EQ -> Just (k0, v)+ GT -> M.lookupGE k m+{-# INLINE lookupGE #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union with a combining function.+--+-- > unionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "aA"), (7, "C")])+unionWith ::+ Ord k =>+ (a -> a -> a) ->+ NEMap k a ->+ NEMap k a ->+ NEMap k a+unionWith f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEMap k1 v1 . M.unionWith f m1 . toMap $ n2+ EQ -> NEMap k1 (f v1 v2) . M.unionWith f m1 $ m2+ GT -> NEMap k2 v2 . M.unionWith f (toMap n1) $ m2+{-# INLINE unionWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a possibly-empty+-- 'Map' and a non-empty map.+--+-- @since 0.3.6.0+unionMapLeft :: Ord k => Map k a -> NEMap k a -> NEMap k a+unionMapLeft m n = withNonEmpty n (`union` n) m+{-# INLINE unionMapLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Left-biased union of a non-empty map and a+-- possibly-empty 'Map'.+--+-- @since 0.3.6.0+unionMapRight :: Ord k => NEMap k a -> Map k a -> NEMap k a+unionMapRight n = withNonEmpty n (union n)+{-# INLINE unionMapRight #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'Map' and a+-- non-empty map with a combining function.+--+-- @since 0.3.6.0+unionMapWithLeft :: Ord k => (a -> a -> a) -> Map k a -> NEMap k a -> NEMap k a+unionMapWithLeft f m n = withNonEmpty n (\m' -> unionWith f m' n) m+{-# INLINE unionMapWithLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a+-- possibly-empty 'Map' with a combining function.+--+-- @since 0.3.6.0+unionMapWithRight :: Ord k => (a -> a -> a) -> NEMap k a -> Map k a -> NEMap k a+unionMapWithRight f n = withNonEmpty n (unionWith f n)+{-# INLINE unionMapWithRight #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- Union with a combining function, given the matching key.+--+-- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value+-- > unionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == fromList ((3, "b") :| [(5, "5:a|A"), (7, "C")])+unionWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ NEMap k a ->+ NEMap k a ->+ NEMap k a+unionWithKey f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEMap k1 v1 . M.unionWithKey f m1 . toMap $ n2+ EQ -> NEMap k1 (f k1 v1 v2) . M.unionWithKey f m1 $ m2+ GT -> NEMap k2 v2 . M.unionWithKey f (toMap n1) $ m2+{-# INLINE unionWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a possibly-empty 'Map' and a+-- non-empty map with a combining function, given the matching key.+--+-- @since 0.3.6.0+unionMapWithKeyLeft ::+ Ord k =>+ (k -> a -> a -> a) ->+ Map k a ->+ NEMap k a ->+ NEMap k a+unionMapWithKeyLeft f m n = withNonEmpty n (\m' -> unionWithKey f m' n) m+{-# INLINE unionMapWithKeyLeft #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Union of a non-empty map and a+-- possibly-empty 'Map' with a combining function, given the matching key.+--+-- @since 0.3.6.0+unionMapWithKeyRight ::+ Ord k =>+ (k -> a -> a -> a) ->+ NEMap k a ->+ Map k a ->+ NEMap k a+unionMapWithKeyRight f n = withNonEmpty n (unionWithKey f n)+{-# INLINE unionMapWithKeyRight #-}++-- | The union of a non-empty list of maps, with a combining operation:+-- (@'unionsWith' f == 'Data.Foldable.foldl1' ('unionWith' f)@).+--+-- > unionsWith (++) (fromList ((5, "a") :| [(3, "b")]) :| [fromList ((5, "A") :| [(7, "C")]), fromList ((5, "A3") :| [(3, "B3")])])+-- > == fromList ((3, "bB3") :| [(5, "aAA3"), (7, "C")])+unionsWith ::+ (Foldable1 f, Ord k) =>+ (a -> a -> a) ->+ f (NEMap k a) ->+ NEMap k a+unionsWith f (F1.toNonEmpty -> (m :| ms)) = F.foldl' (unionWith f) m ms+{-# INLINE unionsWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Difference of two maps.+-- Return elements of the first map not existing in the second map.+--+-- Returns a potentially empty map ('Map'), in case the first map is+-- a subset of the second map.+--+-- > difference (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 3 "b"+difference ::+ Ord k =>+ NEMap k a ->+ NEMap k b ->+ Map k a+difference n1@(NEMap k1 v1 m1) n2@(NEMap k2 _ m2) = case compare k1 k2 of+ -- k1 is not in n2, so cannot be deleted+ LT -> insertMinMap k1 v1 $ m1 `M.difference` toMap n2+ -- k2 deletes k1, and only k1+ EQ -> m1 `M.difference` m2+ -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.+ GT -> toMap n1 `M.difference` m2+{-# INLINE difference #-}++-- | Same as 'difference'.+(\\) ::+ Ord k =>+ NEMap k a ->+ NEMap k b ->+ Map k a+(\\) = difference+{-# INLINE (\\) #-}++-- | /O(n+m)/. Difference with a combining function.+-- When two equal keys are+-- encountered, the combining function is applied to the values of these keys.+-- 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@.+--+-- Returns a potentially empty map ('Map'), in case the first map is+-- a subset of the second map and the function returns 'Nothing' for every+-- pair.+--+-- > let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing+-- > differenceWith f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (7, "C")]))+-- > == Data.Map.singleton 3 "b:B"+differenceWith ::+ Ord k =>+ (a -> b -> Maybe a) ->+ NEMap k a ->+ NEMap k b ->+ Map k a+differenceWith f = differenceWithKey (const f)+{-# INLINE differenceWith #-}++-- | /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@.+--+-- Returns a potentially empty map ('Map'), in case the first map is+-- a subset of the second map and the function returns 'Nothing' for every+-- pair.+--+-- > let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing+-- > differenceWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(3, "B"), (10, "C")]))+-- > == Data.Map.singleton 3 "3:b|B"+differenceWithKey ::+ Ord k =>+ (k -> a -> b -> Maybe a) ->+ NEMap k a ->+ NEMap k b ->+ Map k a+differenceWithKey f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ -- k1 is not in n2, so cannot be deleted+ LT -> insertMinMap k1 v1 $ M.differenceWithKey f m1 (toMap n2)+ -- k2 deletes k1, and only k1+ EQ -> maybe id (insertMinMap k1) (f k1 v1 v2) (M.differenceWithKey f m1 m2)+ -- k2 is not in n1, so cannot delete anything, so we can just difference n1 // m2.+ GT -> M.differenceWithKey f (toMap n1) m2+{-# INLINE differenceWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection of two maps.+-- Return data in the first map for the keys existing in both maps.+-- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).+--+-- Returns a potentially empty map ('Map'), in case the two maps share no+-- keys in common.+--+-- > intersection (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 5 "a"+intersection ::+ Ord k =>+ NEMap k a ->+ NEMap k b ->+ Map k a+intersection n1@(NEMap k1 v1 m1) n2@(NEMap k2 _ m2) = case compare k1 k2 of+ -- k1 is not in n2+ LT -> m1 `M.intersection` toMap n2+ -- k1 and k2 are a part of the result+ EQ -> insertMinMap k1 v1 $ m1 `M.intersection` m2+ -- k2 is not in n1+ GT -> toMap n1 `M.intersection` m2+{-# INLINE intersection #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.+--+-- Returns a potentially empty map ('Map'), in case the two maps share no+-- keys in common.+--+-- > intersectionWith (++) (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 5 "aA"+intersectionWith ::+ Ord k =>+ (a -> b -> c) ->+ NEMap k a ->+ NEMap k b ->+ Map k c+intersectionWith f = intersectionWithKey (const f)+{-# INLINE intersectionWith #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Intersection with a combining function.+--+-- Returns a potentially empty map ('Map'), in case the two maps share no+-- keys in common.+--+-- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar+-- > intersectionWithKey f (fromList ((5, "a") :| [(3, "b")])) (fromList ((5, "A") :| [(7, "C")])) == Data.Map.singleton 5 "5:a|A"+intersectionWithKey ::+ Ord k =>+ (k -> a -> b -> c) ->+ NEMap k a ->+ NEMap k b ->+ Map k c+intersectionWithKey f n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ -- k1 is not in n2+ LT -> M.intersectionWithKey f m1 (toMap n2)+ -- k1 and k2 are a part of the result+ EQ -> insertMinMap k1 (f k1 v1 v2) $ M.intersectionWithKey f m1 m2+ -- k2 is not in n1+ GT -> M.intersectionWithKey f (toMap n1) m2+{-# INLINE intersectionWithKey #-}++-- | /O(n)/. A strict version of 'foldr1'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldr1' :: (a -> a -> a) -> NEMap k a -> a+foldr1' f (NEMap _ v m) = case M.maxView m of+ Nothing -> v+ Just (y, m') -> let !z = M.foldr' f y m' in v `f` z+{-# INLINE foldr1' #-}++-- | /O(n)/. A strict version of 'foldl1'. Each application of the operator+-- is evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldl1' :: (a -> a -> a) -> NEMap k a -> a+foldl1' f (NEMap _ v m) = M.foldl' f v m+{-# INLINE foldl1' #-}++-- | /O(n)/. Fold the keys and values in the map using the given right-associative+-- binary operator, such that+-- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.+--+-- For example,+--+-- > keysList map = foldrWithKey (\k x ks -> k:ks) [] map+foldrWithKey :: (k -> a -> b -> b) -> b -> NEMap k a -> b+foldrWithKey f z (NEMap k v m) = f k v . M.foldrWithKey f z $ m+{-# INLINE foldrWithKey #-}++-- | /O(n)/. A strict version of 'foldrWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldrWithKey' :: (k -> a -> b -> b) -> b -> NEMap k a -> b+foldrWithKey' f z (NEMap k v m) = f k v y+ where+ !y = M.foldrWithKey f z m+{-# INLINE foldrWithKey' #-}++-- | /O(n)/. Fold the keys and values in the map using the given left-associative+-- binary operator, such that+-- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.+--+-- For example,+--+-- > keysList = reverse . foldlWithKey (\ks k x -> k:ks) []+foldlWithKey :: (a -> k -> b -> a) -> a -> NEMap k b -> a+foldlWithKey f z (NEMap k v m) = M.foldlWithKey f (f z k v) m+{-# INLINE foldlWithKey #-}++-- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldlWithKey' :: (a -> k -> b -> a) -> a -> NEMap k b -> a+foldlWithKey' f z (NEMap k v m) = M.foldlWithKey' f x m+ where+ !x = f z k v+{-# INLINE foldlWithKey' #-}++-- | /O(n)/. Return all keys of the map in ascending order.+--+-- > keys (fromList ((5,"a") :| [(3,"b")])) == (3 :| [5])+keys :: NEMap k a -> NonEmpty k+keys (NEMap k _ m) = k :| M.keys m+{-# INLINE keys #-}++-- | /O(n)/. An alias for 'toAscList'. Return all key\/value pairs in the map+-- in ascending key order.+--+-- > assocs (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+assocs :: NEMap k a -> NonEmpty (k, a)+assocs = toList+{-# INLINE assocs #-}++-- | /O(n)/. The non-empty set of all keys of the map.+--+-- > keysSet (fromList ((5,"a") :| [(3,"b")])) == Data.Set.NonEmpty.fromList (3 :| [5])+keysSet :: NEMap k a -> NESet k+keysSet (NEMap k _ m) = NESet k (M.keysSet m)+{-# INLINE keysSet #-}++-- | /O(n)/. Map a function over all values in the map.+--+-- > let f key x = (show key) ++ ":" ++ x+-- > mapWithKey f (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "3:b") :| [(5, "5:a")])+mapWithKey :: (k -> a -> b) -> NEMap k a -> NEMap k b+mapWithKey f (NEMap k v m) = NEMap k (f k v) (M.mapWithKey f m)+{-# NOINLINE [1] mapWithKey #-}++{-# RULES+"mapWithKey/mapWithKey" forall f g xs.+ mapWithKey f (mapWithKey g xs) =+ mapWithKey (\k a -> f k (g k a)) xs+"mapWithKey/map" forall f g xs.+ mapWithKey f (map g xs) =+ mapWithKey (\k a -> f k (g a)) xs+"map/mapWithKey" forall f g xs.+ map f (mapWithKey g xs) =+ mapWithKey (\k a -> f (g k a)) xs+ #-}++-- | /O(n)/. Convert the map to a list of key\/value pairs where the keys are+-- in ascending order.+--+-- > toAscList (fromList ((5,"a") :| [(3,"b")])) == ((3,"b") :| [(5,"a")])+toAscList :: NEMap k a -> NonEmpty (k, a)+toAscList = toList+{-# INLINE toAscList #-}++-- | /O(n)/. Convert the map to a list of key\/value pairs where the keys+-- are in descending order.+--+-- > toDescList (fromList ((5,"a") :| [(3,"b")])) == ((5,"a") :| [(3,"b")])+toDescList :: NEMap k a -> NonEmpty (k, a)+toDescList (NEMap k0 v0 m) = M.foldlWithKey' go ((k0, v0) :| []) m+ where+ go xs k v = (k, v) NE.<| xs+{-# INLINE toDescList #-}++-- | /O(log n)/. Convert a 'Map' into an 'NEMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. If key is already present,+-- will overwrite the original value.+--+-- See 'insertMapMin' for a version that is constant-time if the new key is+-- /strictly smaller than/ all keys in the original map.+--+-- > insertMap 4 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])+-- > insertMap 4 "c" Data.Map.empty == singleton 4 "c"+insertMap :: Ord k => k -> a -> Map k a -> NEMap k a+insertMap k v = withNonEmpty (singleton k v) (insert k v)+{-# INLINE insertMap #-}++-- | /O(log n)/. Convert a 'Map' into an 'NEMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. Uses a combining function+-- with the new value as the first argument if the key is already present.+--+-- > insertMapWith (++) 4 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(4,"c"), (5,"a")])+-- > insertMapWith (++) 5 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"ca")])+insertMapWith ::+ Ord k =>+ (a -> a -> a) ->+ k ->+ a ->+ Map k a ->+ NEMap k a+insertMapWith f k v = withNonEmpty (singleton k v) (insertWith f k v)+{-# INLINE insertMapWith #-}++-- | /O(log n)/. Convert a 'Map' into an 'NEMap' by adding a key-value+-- pair. Because of this, we know that the map must have at least one+-- element, and so therefore cannot be empty. Uses a combining function+-- with the key and new value as the first and second arguments if the key+-- is already present.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "5:xxx|a")])+-- > insertWithKey f 7 "xxx" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+-- > insertWithKey f 5 "xxx" Data.Map.empty == singleton 5 "xxx"+insertMapWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ k ->+ a ->+ Map k a ->+ NEMap k a+insertMapWithKey f k v = withNonEmpty (singleton k v) (insertWithKey f k v)+{-# INLINE insertMapWithKey #-}++-- | /O(1)/ Convert a 'Map' into an 'NEMap' by adding a key-value pair+-- where the key is /strictly less than/ all keys in the input map. The+-- keys in the original map must all be /strictly greater than/ the new+-- key. /The precondition is not checked./+--+-- > insertMapMin 2 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((2,"c") :| [(3,"b"), (5,"a")])+-- > valid (insertMapMin 2 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == True+-- > valid (insertMapMin 7 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False+-- > valid (insertMapMin 3 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False+insertMapMin ::+ k ->+ a ->+ Map k a ->+ NEMap k a+insertMapMin = NEMap+{-# INLINE insertMapMin #-}++-- | /O(log n)/ Convert a 'Map' into an 'NEMap' by adding a key-value pair+-- where the key is /strictly greater than/ all keys in the input map. The+-- keys in the original map must all be /strictly less than/ the new+-- key. /The precondition is not checked./+--+-- While this has the same asymptotics as 'insertMap', it saves a constant+-- factor for key comparison (so may be helpful if comparison is expensive)+-- and also does not require an 'Ord' instance for the key type.+--+-- > insertMap 7 "c" (Data.Map.fromList [(5,"a"), (3,"b")]) == fromList ((3,"b") :| [(5,"a"), (7,"c")])+-- > valid (insertMap 7 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == True+-- > valid (insertMap 2 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False+-- > valid (insertMap 5 "c" (Data.Map.fromList [(5,"a"), (3,"b")])) == False+insertMapMax ::+ k ->+ a ->+ Map k a ->+ NEMap k a+insertMapMax k v = withNonEmpty (singleton k v) go+ where+ go (NEMap k0 v0 m0) = NEMap k0 v0 . insertMaxMap k v $ m0+{-# INLINE insertMapMax #-}++-- | /O(log n)/. Insert a new key and value in the map.+-- If the key is already present in the map, the associated value is+-- replaced with the supplied value. 'insert' is equivalent to+-- @'insertWith' 'const'@.+--+-- See 'insertMap' for a version where the first argument is a 'Map'.+--+-- > insert 5 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'x')])+-- > insert 7 'x' (fromList ((5,'a') :| [(3,'b')])) == fromList ((3, 'b') :| [(5, 'a'), (7, 'x')])+insert ::+ Ord k =>+ k ->+ a ->+ NEMap k a ->+ NEMap k a+insert k v n@(NEMap k0 v0 m) = case compare k k0 of+ LT -> NEMap k v . toMap $ n+ EQ -> NEMap k v m+ GT -> NEMap k0 v0 . M.insert k v $ m+{-# INLINE insert #-}++-- | /O(log n)/. Insert with a function, combining key, new value and old+-- value. @'insertWithKey' f key value mp@ will insert the pair (key,+-- value) into @mp@ if key does not exist in the map. If the key does+-- exist, the function will insert the pair @(key,f key new_value+-- old_value)@. Note that the key passed to f is the same key passed to+-- 'insertWithKey'.+--+-- See 'insertMapWithKey' for a version where the first argument is a 'Map'.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:xxx|a")])+-- > insertWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a"), (7, "xxx")])+insertWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ k ->+ a ->+ NEMap k a ->+ NEMap k a+insertWithKey f k v n@(NEMap k0 v0 m) = case compare k k0 of+ LT -> NEMap k v . toMap $ n+ EQ -> NEMap k (f k v v0) m+ GT -> NEMap k0 v0 $ M.insertWithKey f k v m+{-# INLINE insertWithKey #-}++-- | /O(log n)/. Combines insert operation with old value retrieval. The+-- expression (@'insertLookupWithKey' f k x map@) is a pair where the first+-- element is equal to (@'lookup' k map@) and the second element equal to+-- (@'insertWithKey' f k x map@).+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertLookupWithKey f 5 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "5:xxx|a")]))+-- > insertLookupWithKey f 7 "xxx" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "xxx")]))+--+-- This is how to define @insertLookup@ using @insertLookupWithKey@:+--+-- > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t+-- > insertLookup 5 "x" (fromList ((5,"a") :| [(3,"b")])) == (Just "a", fromList ((3, "b") :| [(5, "x")]))+-- > insertLookup 7 "x" (fromList ((5,"a") :| [(3,"b")])) == (Nothing, fromList ((3, "b") :| [(5, "a"), (7, "x")]))+insertLookupWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ k ->+ a ->+ NEMap k a ->+ (Maybe a, NEMap k a)+insertLookupWithKey f k v n@(NEMap k0 v0 m) = case compare k k0 of+ LT -> (Nothing, NEMap k v . toMap $ n)+ EQ -> (Just v, NEMap k (f k v v0) m)+ GT -> NEMap k0 v0 <$> M.insertLookupWithKey f k v m+{-# INLINE insertLookupWithKey #-}++-- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs+-- with a combining function. See also 'fromAscListWith'.+--+-- > fromListWith (++) ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "ab") :| [(5, "aba")])+fromListWith ::+ Ord k =>+ (a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromListWith f = fromListWithKey (const f)+{-# INLINE fromListWith #-}++-- | /O(n*log n)/. Build a map from a non-empty list of key\/value pairs+-- with a combining function. See also 'fromAscListWithKey'.+--+-- > let f k a1 a2 = (show k) ++ a1 ++ a2+-- > fromListWithKey f ((5,"a") :| [(5,"b"), (3,"b"), (3,"a"), (5,"a")]) == fromList ((3, "3ab") :| [(5, "5a5ba")])+fromListWithKey ::+ Ord k =>+ (k -> a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromListWithKey f ((k0, v0) :| xs) = F.foldl' go (singleton k0 v0) xs+ where+ go m (k, v) = insertWithKey f k v m+ {-# INLINE go #-}+{-# INLINE fromListWithKey #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time.+-- /The precondition (input list is ascending) is not checked./+--+-- > fromAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])+-- > fromAscList ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "b")])+-- > valid (fromAscList ((3,"b") :| [(5,"a"), (5,"b")])) == True+-- > valid (fromAscList ((5,"a") :| [(3,"b"), (5,"b")])) == False+fromAscList ::+ Eq k =>+ NonEmpty (k, a) ->+ NEMap k a+fromAscList = fromDistinctAscList . combineEq+{-# INLINE fromAscList #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is ascending) is not checked./+--+-- > fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b")]) == fromList ((3, "b") :| [(5, "ba")])+-- > valid (fromAscListWith (++) ((3,"b") :| [(5,"a"), (5,"b"))]) == True+-- > valid (fromAscListWith (++) ((5,"a") :| [(3,"b"), (5,"b"))]) == False+fromAscListWith ::+ Eq k =>+ (a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromAscListWith f = fromAscListWithKey (const f)+{-# INLINE fromAscListWith #-}++-- | /O(n)/. Build a map from an ascending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is ascending) is not checked./+--+-- > let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2+-- > fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")]) == fromList ((3, "b") :| [(5, "5:b5:ba")])+-- > valid (fromAscListWithKey f ((3,"b") :| [(5,"a"), (5,"b"), (5,"b")])) == True+-- > valid (fromAscListWithKey f ((5,"a") :| [(3,"b"), (5,"b"), (5,"b")])) == False+fromAscListWithKey ::+ Eq k =>+ (k -> a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromAscListWithKey f = fromDistinctAscList . combineEqWith f+{-# INLINE fromAscListWithKey #-}++-- | /O(n)/. Build a map from an ascending non-empty list of distinct+-- elements in linear time. /The precondition is not checked./+--+-- > fromDistinctAscList ((3,"b") :| [(5,"a")]) == fromList ((3, "b") :| [(5, "a")])+-- > valid (fromDistinctAscList ((3,"b") :| [(5,"a")])) == True+-- > valid (fromDistinctAscList ((3,"b") :| [(5,"a"), (5,"b")])) == False+fromDistinctAscList :: NonEmpty (k, a) -> NEMap k a+fromDistinctAscList ((k, v) :| xs) =+ insertMapMin k v+ . M.fromDistinctAscList+ $ xs+{-# INLINE fromDistinctAscList #-}++-- | /O(n)/. Build a map from a descending non-empty list in linear time.+-- /The precondition (input list is descending) is not checked./+--+-- > fromDescList ((5,"a") :| [(3,"b")]) == fromList ((3, "b") :| [(5, "a")])+-- > fromDescList ((5,"a") :| [(5,"b"), (3,"b")]) == fromList ((3, "b") :| [(5, "b")])+-- > valid (fromDescList ((5,"a") :| [(5,"b"), (3,"b")])) == True+-- > valid (fromDescList ((5,"a") :| [(3,"b"), (5,"b")])) == False+fromDescList ::+ Eq k =>+ NonEmpty (k, a) ->+ NEMap k a+fromDescList = fromDistinctDescList . combineEq+{-# INLINE fromDescList #-}++-- | /O(n)/. Build a map from a descending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is descending) is not checked./+--+-- > fromDescListWith (++) ((5,"a") :| [(5,"b"), (3,"b")]) == fromList ((3, "b") :| [(5, "ba")])+-- > valid (fromDescListWith (++) ((5,"a") :| [(5,"b"), (3,"b")])) == True+-- > valid (fromDescListWith (++) ((5,"a") :| [(3,"b"), (5,"b")])) == False+fromDescListWith ::+ Eq k =>+ (a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromDescListWith f = fromDescListWithKey (const f)+{-# INLINE fromDescListWith #-}++-- | /O(n)/. Build a map from a descending non-empty list in linear time+-- with a combining function for equal keys. /The precondition (input list+-- is descending) is not checked./+--+-- > let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2+-- > fromDescListWithKey f ((5,"a") :| [(5,"b"), (5,"b"), (3,"b")]) == fromList ((3, "b") :| [(5, "5:b5:ba")])+-- > valid (fromDescListWithKey f ((5,"a") :| [(5,"b"), (5,"b"), (3,"b")])) == True+-- > valid (fromDescListWithKey f ((5,"a") :| [(3,"b"), (5,"b"), (5,"b")])) == False+fromDescListWithKey ::+ Eq k =>+ (k -> a -> a -> a) ->+ NonEmpty (k, a) ->+ NEMap k a+fromDescListWithKey f = fromDistinctDescList . combineEqWith f+{-# INLINE fromDescListWithKey #-}++-- | /O(n)/. Build a map from a descending list of distinct elements in linear time.+-- /The precondition is not checked./+--+-- > fromDistinctDescList ((5,"a") :| [(3,"b")]) == fromList ((3, "b") :| [(5, "a")])+-- > valid (fromDistinctDescList ((5,"a") :| [(3,"b")])) == True+-- > valid (fromDistinctDescList ((5,"a") :| [(5,"b"), (3,"b")])) == False+--+-- @since 0.5.8+fromDistinctDescList :: NonEmpty (k, a) -> NEMap k a+fromDistinctDescList ((k, v) :| xs) =+ insertMapMax k v+ . M.fromDistinctDescList+ $ xs+{-# INLINE fromDistinctDescList #-}++-- | /O(log n)/. Delete a key and its value from the non-empty map.+-- A potentially empty map ('Map') is returned, since this might delete the+-- last item in the 'NEMap'. When the key is not a member of the map, is+-- equivalent to 'toMap'.+--+-- > delete 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- > delete 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.Singleton [(3, "b"), (5, "a")]+delete :: Ord k => k -> NEMap k a -> Map k a+delete k n@(NEMap k0 v m) = case compare k k0 of+ LT -> toMap n+ EQ -> m+ GT -> insertMinMap k0 v . M.delete k $ m+{-# INLINE delete #-}++-- | /O(log n)/. Delete a key and its value from the non-empty map, returning+-- 'Nothing' if the result would be empty.+--+-- This is more efficient than @'nonEmptyMap' . 'delete' k@ because it avoids+-- converting the known-minimum representation back through 'Map' when the+-- deleted key is not the minimum.+--+-- @since 0.3.6.0+deleteMaybe :: Ord k => k -> NEMap k a -> Maybe (NEMap k a)+deleteMaybe k n@(NEMap k0 v m) = case compare k k0 of+ LT -> Just n+ EQ -> nonEmptyMap m+ GT -> Just . NEMap k0 v . M.delete k $ m+{-# INLINE deleteMaybe #-}++-- | /O(log n)/. Update a value at a specific key with the result of the+-- provided function. When the key is not a member of the map, the original+-- map is returned.+--+-- > adjust ("new " ++) 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "new a")])+-- > adjust ("new " ++) 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])+adjust ::+ Ord k =>+ (a -> a) ->+ k ->+ NEMap k a ->+ NEMap k a+adjust f = adjustWithKey (const f)+{-# INLINE adjust #-}++-- | /O(log n)/. Adjust a value at a specific key. When the key is not+-- a member of the map, the original map is returned.+--+-- > let f key x = (show key) ++ ":new " ++ x+-- > adjustWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "5:new a")])+-- > adjustWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == fromList ((3, "b") :| [(5, "a")])+adjustWithKey ::+ Ord k =>+ (k -> a -> a) ->+ k ->+ NEMap k a ->+ NEMap k a+adjustWithKey f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> n+ EQ -> NEMap k0 (f k0 v) m+ GT -> NEMap k0 v . M.adjustWithKey f k $ m+{-# INLINE adjustWithKey #-}++-- | /O(log n)/. The expression (@'update' f k map@) updates the value @x@+-- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is+-- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.+--+-- Returns a potentially empty map ('Map'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEMap'.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > update f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "new a")]+-- > update f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a")]+-- > update f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+update ::+ Ord k =>+ (a -> Maybe a) ->+ k ->+ NEMap k a ->+ Map k a+update f = updateWithKey (const f)+{-# INLINE update #-}++-- | /O(log n)/. The expression (@'updateWithKey' f k map@) updates the+-- value @x@ at @k@ (if it is in the map). If (@f k x@) is 'Nothing',+-- the element is deleted. If it is (@'Just' y@), the key @k@ is bound+-- to the new value @y@.+--+-- Returns a potentially empty map ('Map'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEMap'.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "5:new a")]+-- > updateWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a")]+-- > updateWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+updateWithKey ::+ Ord k =>+ (k -> a -> Maybe a) ->+ k ->+ NEMap k a ->+ Map k a+updateWithKey f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> toMap n+ EQ -> maybe m (flip (insertMinMap k0) m) . f k0 $ v+ GT -> insertMinMap k0 v . M.updateWithKey f k $ m+{-# INLINE updateWithKey #-}++-- | /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 a potentially empty map ('Map') in the case that we delete the+-- final key of a singleton map.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateLookupWithKey f 5 (fromList ((5,"a") :| [(3,"b")])) == (Just "5:new a", Data.Map.fromList ((3, "b") :| [(5, "5:new a")]))+-- > updateLookupWithKey f 7 (fromList ((5,"a") :| [(3,"b")])) == (Nothing, Data.Map.fromList ((3, "b") :| [(5, "a")]))+-- > updateLookupWithKey f 3 (fromList ((5,"a") :| [(3,"b")])) == (Just "b", Data.Map.singleton 5 "a")+updateLookupWithKey ::+ Ord k =>+ (k -> a -> Maybe a) ->+ k ->+ NEMap k a ->+ (Maybe a, Map k a)+updateLookupWithKey f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> (Nothing, toMap n)+ EQ ->+ let u = f k0 v+ in (u <|> Just v, maybe m (flip (insertMinMap k0) m) u)+ GT -> fmap (insertMinMap k0 v) . M.updateLookupWithKey f k $ m+{-# INLINE updateLookupWithKey #-}++-- | /O(log n)/. The expression (@'alter' f k map@) alters the value @x@ at+-- @k@, or absence thereof. 'alter' can be used to insert, delete, or+-- update a value in a 'Map'. In short : @Data.Map.lookup k ('alter'+-- f k m) = f ('lookup' k m)@.+--+-- Returns a potentially empty map ('Map'), because we can't know ahead of+-- time if the function returns 'Nothing' and deletes the final item in the+-- 'NEMap'.+--+-- See 'alterF'' for a version that disallows deletion, and so therefore+-- can return 'NEMap'.+--+-- > let f _ = Nothing+-- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a")]+-- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- >+-- > let f _ = Just "c"+-- > alter f 7 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "a"), (7, "c")]+-- > alter f 5 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "c")]+alter ::+ Ord k =>+ (Maybe a -> Maybe a) ->+ k ->+ NEMap k a ->+ Map k a+alter f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> maybe id (insertMinMap k) (f Nothing) (toMap n)+ EQ -> maybe id (insertMinMap k0) (f (Just v)) m+ GT -> insertMinMap k0 v . M.alter f k $ m+{-# INLINE alter #-}++-- | /O(log n)/. The expression (@'alterF' f k map@) alters the value @x@+-- at @k@, or absence thereof. 'alterF' can be used to inspect, insert,+-- delete, or update a value in a 'Map'. In short: @Data.Map.lookup+-- k \<$\> 'alterF' f k m = f ('lookup' k m)@.+--+-- Example:+--+-- @+-- interactiveAlter :: Int -> NEMap Int String -> IO (Map Int String)+-- interactiveAlter k m = alterF f k m where+-- f Nothing = do+-- putStrLn $ show k +++-- " was not found in the map. Would you like to add it?"+-- getUserResponse1 :: IO (Maybe String)+-- f (Just old) = do+-- putStrLn $ "The key is currently bound to " ++ show old +++-- ". Would you like to change or delete it?"+-- getUserResponse2 :: IO (Maybe String)+-- @+--+-- Like @Data.Map.alterF@ for 'Map', 'alterF' can be considered+-- to be a unifying generalization of 'lookup' and 'delete'; however, as+-- a constrast, it cannot be used to implement 'insert', because it must+-- return a 'Map' instead of an 'NEMap' (because the function might delete+-- the final item in the 'NEMap'). When used with trivial functors like+-- 'Identity' and 'Const', it is often slightly slower than+-- specialized 'lookup' and 'delete'. However, when the functor is+-- non-trivial and key comparison is not particularly cheap, it is the+-- fastest way.+--+-- See 'alterF'' for a version that disallows deletion, and so therefore+-- can return 'NEMap' and be used to implement 'insert'+--+-- Note on rewrite rules:+--+-- This module includes GHC rewrite rules to optimize 'alterF' for+-- the 'Const' and 'Identity' functors. In general, these rules+-- improve performance. The sole exception is that when using+-- 'Identity', deleting a key that is already absent takes longer+-- than it would without the rules. If you expect this to occur+-- a very large fraction of the time, you might consider using a+-- private copy of the 'Identity' type.+--+-- Note: Unlike @Data.Map.alterF@ for 'Map', 'alterF' is /not/ a flipped+-- version of the 'Control.Lens.At.at' combinator from "Control.Lens.At".+-- However, it match the shape expected from most functions expecting+-- lenses, getters, and setters, so can be thought of as a "psuedo-lens",+-- with virtually the same practical applications as a legitimate lens.+alterF ::+ (Ord k, Functor f) =>+ (Maybe a -> f (Maybe a)) ->+ k ->+ NEMap k a ->+ f (Map k a)+alterF f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> flip (maybe id (insertMinMap k)) (toMap n) <$> f Nothing+ EQ -> flip (maybe id (insertMinMap k0)) m <$> f (Just v)+ GT -> insertMinMap k0 v <$> M.alterF f k m+{-# INLINEABLE [2] alterF #-}++-- if f ~ Const b, it's a lookup+{-# RULES+"alterF/Const" forall k (f :: Maybe a -> Const b (Maybe a)).+ alterF f k =+ Const . getConst . f . lookup k+ #-}++-- if f ~ Identity, it's an 'alter'+{-# RULES+"alterF/Identity" forall k (f :: Maybe a -> Identity (Maybe a)).+ alterF f k =+ Identity . alter (runIdentity . f) k+ #-}++-- | /O(log n)/. Variant of 'alter' that disallows deletion. Allows us to+-- guarantee that the result is also a non-empty Map.+alter' ::+ Ord k =>+ (Maybe a -> a) ->+ k ->+ NEMap k a ->+ NEMap k a+alter' f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> NEMap k (f Nothing) . toMap $ n+ EQ -> NEMap k0 (f (Just v)) m+ GT -> NEMap k0 v . M.alter (Just . f) k $ m+{-# INLINE alter' #-}++-- | /O(log n)/. Variant of 'alterF' that disallows deletion. Allows us to+-- guarantee that the result is also a non-empty Map.+--+-- Like @Data.Map.alterF@ for 'Map', can be used to generalize and unify+-- 'lookup' and 'insert'. However, because it disallows deletion, it+-- cannot be used to implement 'delete'.+--+-- See 'alterF' for usage information and caveats.+--+-- Note: Neither 'alterF' nor 'alterF'' can be considered flipped versions+-- of the 'Control.Lens.At.at' combinator from "Control.Lens.At". However,+-- this can match the shape expected from most functions expecting lenses,+-- getters, and setters, so can be thought of as a "psuedo-lens", with+-- virtually the same practical applications as a legitimate lens.+--+-- __WARNING__: The rewrite rule for 'Identity' exposes an inconsistency in+-- undefined behavior for "Data.Map". @Data.Map.alterF@ will actually+-- /maintain/ the original key in the map when used with 'Identity';+-- however, @Data.Map.insertWith@ will /replace/ the orginal key in the+-- map. The rewrite rule for 'alterF'' has chosen to be faithful to+-- @Data.Map.insertWith@, and /not/ @Data.Map.alterF@, for the sake of+-- a cleaner implementation.+alterF' ::+ (Ord k, Functor f) =>+ (Maybe a -> f a) ->+ k ->+ NEMap k a ->+ f (NEMap k a)+alterF' f k n@(NEMap k0 v m) = case compare k k0 of+ LT -> flip (NEMap k) (toMap n) <$> f Nothing+ EQ -> flip (NEMap k0) m <$> f (Just v)+ GT -> NEMap k0 v <$> M.alterF (fmap Just . f) k m+{-# INLINEABLE [2] alterF' #-}++-- if f ~ Const b, it's a lookup+{-# RULES+"alterF'/Const" forall k (f :: Maybe a -> Const b a).+ alterF' f k =+ Const . getConst . f . lookup k+ #-}++-- if f ~ Identity, it's an insertWith+{-# RULES+"alterF'/Identity" forall k (f :: Maybe a -> Identity a).+ alterF' f k =+ Identity . insertWith (\_ -> runIdentity . f . Just) k (runIdentity (f Nothing))+ #-}++-- | /O(n)/. Traverse keys\/values and collect the 'Just' results.+--+-- Returns a potentially empty map ('Map'), our function might return+-- 'Nothing' on every item in the 'NEMap'.+--+-- /Use 'traverseMaybeWithKey1'/ whenever possible (if your 'Applicative'+-- also has 'Apply' instance). This version is provided only for types+-- that do not have 'Apply' instance, since 'Apply' is not at the moment+-- (and might not ever be) an official superclass of 'Applicative'.+traverseMaybeWithKey ::+ Applicative t =>+ (k -> a -> t (Maybe b)) ->+ NEMap k a ->+ t (Map k b)+traverseMaybeWithKey f (NEMap k0 v m0) =+ combine <$> f k0 v <*> M.traverseMaybeWithKey f m0+ where+ combine Nothing = id+ combine (Just v') = insertMinMap k0 v'+{-# INLINE traverseMaybeWithKey #-}++-- | /O(n)/. Traverse keys\/values and collect the 'Just' results.+--+-- Returns a potentially empty map ('Map'), our function might return+-- 'Nothing' on every item in the 'NEMap'.+--+-- Is more general than 'traverseWithKey', since works with all 'Apply',+-- and not just 'Applicative'.++-- TODO: benchmark against M.maxView version+traverseMaybeWithKey1 ::+ Apply t =>+ (k -> a -> t (Maybe b)) ->+ NEMap k a ->+ t (Map k b)+traverseMaybeWithKey1 f (NEMap k0 v m0) = case runMaybeApply m1 of+ Left m2 -> combine <$> f k0 v <.> m2+ Right m2 -> (`combine` m2) <$> f k0 v+ where+ m1 = M.traverseMaybeWithKey (\k -> MaybeApply . Left . f k) m0+ combine Nothing = id+ combine (Just v') = insertMinMap k0 v'+{-# INLINE traverseMaybeWithKey1 #-}++-- | /O(n)/. The function 'mapAccum' threads an accumulating argument+-- through the map in ascending order of keys.+--+-- > let f a b = (a ++ b, b ++ "X")+-- > mapAccum f "Everything: " (fromList ((5,"a") :| [(3,"b")])) == ("Everything: ba", fromList ((3, "bX") :| [(5, "aX")]))+mapAccum ::+ (a -> b -> (a, c)) ->+ a ->+ NEMap k b ->+ (a, NEMap k c)+mapAccum f = mapAccumWithKey (\x _ -> f x)+{-# INLINE mapAccum #-}++-- | /O(n)/. The function 'mapAccumWithKey' threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")+-- > mapAccumWithKey f "Everything:" (fromList ((5,"a") :| [(3,"b")])) == ("Everything: 3-b 5-a", fromList ((3, "bX") :| [(5, "aX")]))+mapAccumWithKey ::+ (a -> k -> b -> (a, c)) ->+ a ->+ NEMap k b ->+ (a, NEMap k c)+mapAccumWithKey f z0 (NEMap k v m) = (z2, NEMap k v' m')+ where+ ~(z1, v') = f z0 k v+ ~(z2, m') = M.mapAccumWithKey f z1 m+{-# INLINE mapAccumWithKey #-}++-- | /O(n)/. The function 'mapAccumRWithKey' threads an accumulating+-- argument through the map in descending order of keys.+mapAccumRWithKey ::+ (a -> k -> b -> (a, c)) ->+ a ->+ NEMap k b ->+ (a, NEMap k c)+mapAccumRWithKey f z0 (NEMap k v m) = (z2, NEMap k v' m')+ where+ ~(z1, m') = M.mapAccumRWithKey f z0 m+ ~(z2, v') = f z1 k v+{-# INLINE mapAccumRWithKey #-}++-- TODO: what other situations can we take advantage of lazy tuple pattern+-- matching?++-- | /O(n*log n)/.+-- @'mapKeys' 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 value at the greatest of the+-- original keys is retained.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeys (+ 1) (fromList ((5,"a") :| [(3,"b")])) == fromList ((4, "b") :| [(6, "a")])+-- > mapKeys (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "c"+-- > mapKeys (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "c"+mapKeys ::+ Ord k2 =>+ (k1 -> k2) ->+ NEMap k1 a ->+ NEMap k2 a+mapKeys f (NEMap k0 v0 m) =+ fromListWith const+ . ((f k0, v0) :|)+ . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []+ $ m+{-# INLINEABLE mapKeys #-}++-- | /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@. The value at the greater of the two original keys+-- is used as the first argument to @c@.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeysWith (++) (\ _ -> 1) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 1 "cdab"+-- > mapKeysWith (++) (\ _ -> 3) (fromList ((1,"b") :| [(2,"a"), (3,"d"), (4,"c")])) == singleton 3 "cdab"+mapKeysWith ::+ Ord k2 =>+ (a -> a -> a) ->+ (k1 -> k2) ->+ NEMap k1 a ->+ NEMap k2 a+mapKeysWith c f (NEMap k0 v0 m) =+ fromListWith c+ . ((f k0, v0) :|)+ . M.foldrWithKey (\k v kvs -> (f k, v) : kvs) []+ $ m+{-# INLINEABLE mapKeysWith #-}++-- | /O(n)/.+-- @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@+-- is strictly monotonic.+-- 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]+-- > ==> mapKeysMonotonic f s == mapKeys f s+-- > where ls = keys s+--+-- This means that @f@ maps distinct original keys to distinct resulting keys.+-- This function has better performance than 'mapKeys'.+--+-- While the size of the result map may be smaller than the input map, the+-- output map is still guaranteed to be non-empty if the input map is+-- non-empty.+--+-- > mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")])) == fromList ((6, "b") :| [(10, "a")])+-- > valid (mapKeysMonotonic (\ k -> k * 2) (fromList ((5,"a") :| [(3,"b")]))) == True+-- > valid (mapKeysMonotonic (\ _ -> 1) (fromList ((5,"a") :| [(3,"b")]))) == False+mapKeysMonotonic ::+ (k1 -> k2) ->+ NEMap k1 a ->+ NEMap k2 a+mapKeysMonotonic f (NEMap k v m) =+ NEMap (f k) v+ . M.mapKeysMonotonic f+ $ m+{-# INLINE mapKeysMonotonic #-}++-- | /O(n)/. Filter all values that satisfy the predicate.+--+-- Returns a potentially empty map ('Map'), because we could+-- potentailly filter out all items in the original 'NEMap'.+--+-- > filter (> "a") (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- > filter (> "x") (fromList ((5,"a") :| [(3,"b")])) == Data.Map.empty+-- > filter (< "a") (fromList ((5,"a") :| [(3,"b")])) == Data.Map.empty+filter ::+ (a -> Bool) ->+ NEMap k a ->+ Map k a+filter f (NEMap k v m)+ | f v = insertMinMap k v . M.filter f $ m+ | otherwise = M.filter f m+{-# INLINE filter #-}++-- | /O(n)/. Filter all keys\/values that satisfy the predicate.+--+-- Returns a potentially empty map ('Map'), because we could+-- potentailly filter out all items in the original 'NEMap'.+--+-- > filterWithKey (\k _ -> k > 4) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+filterWithKey ::+ (k -> a -> Bool) ->+ NEMap k a ->+ Map k a+filterWithKey f (NEMap k v m)+ | f k v = insertMinMap k v . M.filterWithKey f $ m+ | otherwise = M.filterWithKey f m+{-# INLINE filterWithKey #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Restrict an 'NEMap' to only those keys+-- found in a 'Data.Set.Set'.+--+-- @+-- m \`restrictKeys\` s = 'filterWithKey' (\k _ -> k ``Set.member`` s) m+-- m \`restrictKeys\` s = m ``intersection`` 'fromSet' (const ()) s+-- @+restrictKeys ::+ Ord k =>+ NEMap k a ->+ Set k ->+ Map k a+restrictKeys n@(NEMap k v m) xs = case S.minView xs of+ Nothing -> M.empty+ Just (y, ys) -> case compare k y of+ -- k is not in xs+ LT -> m `M.restrictKeys` xs+ -- k and y are a part of the result+ EQ -> insertMinMap k v $ m `M.restrictKeys` ys+ -- y is not in m+ GT -> toMap n `M.restrictKeys` ys+{-# INLINE restrictKeys #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Remove all keys in a 'Data.Set.Set' from+-- an 'NEMap'.+--+-- @+-- m \`withoutKeys\` s = 'filterWithKey' (\k _ -> k ``Set.notMember`` s) m+-- m \`withoutKeys\` s = m ``difference`` 'fromSet' (const ()) s+-- @+withoutKeys ::+ Ord k =>+ NEMap k a ->+ Set k ->+ Map k a+withoutKeys n@(NEMap k v m) xs = case S.minView xs of+ Nothing -> toMap n+ Just (y, ys) -> case compare k y of+ -- k is not in xs, so cannot be deleted+ LT -> insertMinMap k v $ m `M.withoutKeys` xs+ -- y deletes k, and only k+ EQ -> m `M.withoutKeys` ys+ -- y is not in n, so cannot delete anything, so we can just difference n and ys+ GT -> toMap n `M.withoutKeys` ys+{-# INLINE withoutKeys #-}++-- | /O(n)/. Partition the map according to a predicate.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate was true for all items.+-- * @'That' n2@ means that the predicate was false for all items.+-- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the+-- predicate) and @n2@ (all of the items that were false for the+-- predicate).+--+-- See also 'split'.+--+-- > partition (> "a") (fromList ((5,"a") :| [(3,"b")])) == These (singleton 3 "b") (singleton 5 "a")+-- > partition (< "x") (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))+-- > partition (> "x") (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))+partition ::+ (a -> Bool) ->+ NEMap k a ->+ These (NEMap k a) (NEMap k a)+partition f = partitionWithKey (const f)+{-# INLINE partition #-}++-- | /O(n)/. Partition the map according to a predicate.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate was true for all items,+-- returning the original map.+-- * @'That' n2@ means that the predicate was false for all items,+-- returning the original map.+-- * @'These' n1 n2@ gives @n1@ (all of the items that were true for the+-- predicate) and @n2@ (all of the items that were false for the+-- predicate).+--+-- See also 'split'.+--+-- > partitionWithKey (\ k _ -> k > 3) (fromList ((5,"a") :| [(3,"b")])) == These (singleton 5 "a") (singleton 3 "b")+-- > partitionWithKey (\ k _ -> k < 7) (fromList ((5,"a") :| [(3,"b")])) == This (fromList ((3, "b") :| [(5, "a")]))+-- > partitionWithKey (\ k _ -> k > 7) (fromList ((5,"a") :| [(3,"b")])) == That (fromList ((3, "b") :| [(5, "a")]))+partitionWithKey ::+ (k -> a -> Bool) ->+ NEMap k a ->+ These (NEMap k a) (NEMap k a)+partitionWithKey f n@(NEMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing)+ | f k v -> This n+ | otherwise -> That n+ (Just n1, Nothing)+ | f k v -> This n+ | otherwise -> These n1 (singleton k v)+ (Nothing, Just n2)+ | f k v -> These (singleton k v) n2+ | otherwise -> That n+ (Just n1, Just n2)+ | f k v -> These (insertMapMin k v m1) n2+ | otherwise -> These n1 (insertMapMin k v m2)+ where+ (m1, m2) = M.partitionWithKey f m0+{-# INLINEABLE partitionWithKey #-}++-- | /O(log n)/. Take while a predicate on the keys holds.+-- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,+-- @j \< k ==\> p j \>= p k@. See note at 'spanAntitone'.+--+-- Returns a potentially empty map ('Map'), because the predicate might+-- fail on the first input.+--+-- @+-- takeWhileAntitone p = Data.Map.fromDistinctAscList . Data.List.takeWhile (p . fst) . Data.Foldable.toList+-- takeWhileAntitone p = 'filterWithKey' (\k _ -> p k)+-- @+takeWhileAntitone ::+ (k -> Bool) ->+ NEMap k a ->+ Map k a+takeWhileAntitone f (NEMap k v m)+ | f k = insertMinMap k v . M.takeWhileAntitone f $ m+ | otherwise = M.empty+{-# INLINE takeWhileAntitone #-}++-- | /O(log n)/. Drop while a predicate on the keys holds.+-- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,+-- @j \< k ==\> p j \>= p k@. See note at 'spanAntitone'.+--+-- @+-- dropWhileAntitone p = Data.Map.fromDistinctAscList . Data.List.dropWhile (p . fst) . Data.Foldable.toList+-- dropWhileAntitone p = 'filterWithKey' (\k -> not (p k))+-- @+dropWhileAntitone ::+ (k -> Bool) ->+ NEMap k a ->+ Map k a+dropWhileAntitone f n@(NEMap k _ m)+ | f k = M.dropWhileAntitone f m+ | otherwise = toMap n+{-# INLINE dropWhileAntitone #-}++-- | /O(log n)/. Divide a map at the point where a predicate on the keys stops holding.+-- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,+-- @j \< k ==\> p j \>= p k@.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the predicate never failed for any item,+-- returning the original map.+-- * @'That' n2@ means that the predicate failed for the first item,+-- returning the original map.+-- * @'These' n1 n2@ gives @n1@ (the map up to the point where the+-- predicate on the keys stops holding) and @n2@ (the map starting from+-- the point where the predicate stops holding)+--+-- @+-- spanAntitone p xs = partitionWithKey (\k _ -> p k) xs+-- @+--+-- Note: if @p@ is not actually antitone, then @spanAntitone@ will split the map+-- at some /unspecified/ point where the predicate switches from holding to not+-- holding (where the predicate is seen to hold before the first key and to fail+-- after the last key).+spanAntitone ::+ (k -> Bool) ->+ NEMap k a ->+ These (NEMap k a) (NEMap k a)+spanAntitone f n@(NEMap k v m0)+ | f k = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This n+ (Just _, Nothing) -> This n+ (Nothing, Just n2) -> These (singleton k v) n2+ (Just _, Just n2) -> These (insertMapMin k v m1) n2+ | otherwise = That n+ where+ (m1, m2) = M.spanAntitone f m0+{-# INLINEABLE spanAntitone #-}++-- | /O(n)/. Map values and collect the 'Just' results.+--+-- Returns a potentially empty map ('Map'), because the function could+-- potentially return 'Nothing' on all items in the 'NEMap'.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > mapMaybe f (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "new a"+mapMaybe ::+ (a -> Maybe b) ->+ NEMap k a ->+ Map k b+mapMaybe f = mapMaybeWithKey (const f)+{-# INLINE mapMaybe #-}++-- | /O(n)/. Map keys\/values and collect the 'Just' results.+--+-- Returns a potentially empty map ('Map'), because the function could+-- potentially return 'Nothing' on all items in the 'NEMap'.+--+-- > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing+-- > mapMaybeWithKey f (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "key : 3"+mapMaybeWithKey ::+ (k -> a -> Maybe b) ->+ NEMap k a ->+ Map k b+mapMaybeWithKey f (NEMap k v m) = maybe id (insertMinMap k) (f k v) (M.mapMaybeWithKey f m)+{-# INLINE mapMaybeWithKey #-}++-- | /O(n)/. Map values and separate the 'Left' and 'Right' results.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the results were all 'Left'.+-- * @'That' n2@ means that the results were all 'Right'.+-- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')+-- and @n2@ (the map where the results were 'Right')+--+-- > let f a = if a < "c" then Left a else Right a+-- > mapEither f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == These (fromList ((3,"b") :| [(5,"a")])) (fromList ((1,"x") :| [(7,"z")]))+-- >+-- > mapEither (\ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == That (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+mapEither ::+ (a -> Either b c) ->+ NEMap k a ->+ These (NEMap k b) (NEMap k c)+mapEither f = mapEitherWithKey (const f)+{-# INLINE mapEither #-}++-- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results.+--+-- Returns a 'These' with potentially two non-empty maps:+--+-- * @'This' n1@ means that the results were all 'Left'.+-- * @'That' n2@ means that the results were all 'Right'.+-- * @'These' n1 n2@ gives @n1@ (the map where the results were 'Left')+-- and @n2@ (the map where the results were 'Right')+--+-- > let f k a = if k < 5 then Left (k * 2) else Right (a ++ a)+-- > mapEitherWithKey f (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == These (fromList ((1,2) :| [(3,6)])) (fromList ((5,"aa") :| [(7,"zz")]))+-- >+-- > mapEitherWithKey (\_ a -> Right a) (fromList ((5,"a") :| [(3,"b"), (1,"x"), (7,"z")]))+-- > == That (fromList ((1,"x") :| [(3,"b"), (5,"a"), (7,"z")]))+mapEitherWithKey ::+ (k -> a -> Either b c) ->+ NEMap k a ->+ These (NEMap k b) (NEMap k c)+mapEitherWithKey f (NEMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> case f k v of+ Left v' -> This (singleton k v')+ Right v' -> That (singleton k v')+ (Just n1, Nothing) -> case f k v of+ Left v' -> This (insertMapMin k v' m1)+ Right v' -> These n1 (singleton k v')+ (Nothing, Just n2) -> case f k v of+ Left v' -> These (singleton k v') n2+ Right v' -> That (insertMapMin k v' m2)+ (Just n1, Just n2) -> case f k v of+ Left v' -> These (insertMapMin k v' m1) n2+ Right v' -> These n1 (insertMapMin k v' m2)+ where+ (m1, m2) = M.mapEitherWithKey f m0+{-# INLINEABLE mapEitherWithKey #-}++-- | /O(log n)/. The expression (@'split' k map@) is potentially a 'These'+-- containing up to two 'NEMap's based on splitting the map into maps+-- containing items before and after the given key @k@. It will never+-- return a map that contains @k@ itself.+--+-- * 'Nothing' means that @k@ was the only key in the the original map,+-- and so there are no items before or after it.+-- * @'Just' ('This' n1)@ means @k@ was larger than or equal to all items+-- in the map, and @n1@ is the entire original map (minus @k@, if it was+-- present)+-- * @'Just' ('That' n2)@ means @k@ was smaller than or equal to all+-- items in the map, and @n2@ is the entire original map (minus @k@, if+-- it was present)+-- * @'Just' ('These' n1 n2)@ gives @n1@ (the map of all keys from the+-- original map less than @k@) and @n2@ (the map of all keys from the+-- original map greater than @k@)+--+-- > split 2 (fromList ((5,"a") :| [(3,"b")])) == Just (That (fromList ((3,"b") :| [(5,"a")])) )+-- > split 3 (fromList ((5,"a") :| [(3,"b")])) == Just (That (singleton 5 "a") )+-- > split 4 (fromList ((5,"a") :| [(3,"b")])) == Just (These (singleton 3 "b") (singleton 5 "a"))+-- > split 5 (fromList ((5,"a") :| [(3,"b")])) == Just (This (singleton 3 "b") )+-- > split 6 (fromList ((5,"a") :| [(3,"b")])) == Just (This (fromList ((3,"b") :| [(5,"a")])) )+-- > split 5 (singleton 5 "a") == Nothing+split ::+ Ord k =>+ k ->+ NEMap k a ->+ Maybe (These (NEMap k a) (NEMap k a))+split k n@(NEMap k0 v m0) = case compare k k0 of+ LT -> Just $ That n+ EQ -> That <$> nonEmptyMap m0+ GT -> Just $ case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k0 v)+ (Just _, Nothing) -> This (insertMapMin k0 v m1)+ (Nothing, Just n2) -> These (singleton k0 v) n2+ (Just _, Just n2) -> These (insertMapMin k0 v m1) n2+ where+ (m1, m2) = M.split k m0+{-# INLINEABLE split #-}++-- | /O(log n)/. The expression (@'splitLookup' k map@) splits a map just+-- like 'split' but also returns @'lookup' k map@, as the first field in+-- the 'These':+--+-- > splitLookup 2 (fromList ((5,"a") :| [(3,"b")])) == That (That (fromList ((3,"b") :| [(5,"a")])))+-- > splitLookup 3 (fromList ((5,"a") :| [(3,"b")])) == These "b" (That (singleton 5 "a"))+-- > splitLookup 4 (fromList ((5,"a") :| [(3,"b")])) == That (These (singleton 3 "b") (singleton 5 "a"))+-- > splitLookup 5 (fromList ((5,"a") :| [(3,"b")])) == These "a" (This (singleton 3 "b"))+-- > splitLookup 6 (fromList ((5,"a") :| [(3,"b")])) == That (This (fromList ((3,"b") :| [(5,"a")])))+-- > splitLookup 5 (singleton 5 "a") == This "a"+splitLookup ::+ Ord k =>+ k ->+ NEMap k a ->+ These a (These (NEMap k a) (NEMap k a))+splitLookup k n@(NEMap k0 v0 m0) = case compare k k0 of+ LT -> That . That $ n+ EQ -> maybe (This v0) (These v0 . That) . nonEmptyMap $ m0+ GT -> maybe That These v $ case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k0 v0)+ (Just _, Nothing) -> This (insertMapMin k0 v0 m1)+ (Nothing, Just n2) -> These (singleton k0 v0) n2+ (Just _, Just n2) -> These (insertMapMin k0 v0 m1) n2+ where+ (m1, v, m2) = M.splitLookup k m0+{-# INLINEABLE splitLookup #-}++-- | /O(1)/. Decompose a map into pieces based on the structure of the+-- underlying tree. This function is useful for consuming a map in+-- parallel.+--+-- No guarantee is made as to the sizes of the pieces; an internal, but+-- deterministic process determines this. However, it is guaranteed that+-- the pieces returned will be in ascending order (all elements in the+-- first submap less than all elements in the second, and so on).+--+-- Note that the current implementation does not return more than four+-- submaps, but you should not depend on this behaviour because it can+-- change in the future without notice.+splitRoot ::+ NEMap k a ->+ NonEmpty (NEMap k a)+splitRoot (NEMap k v m) =+ singleton k v+ :| Maybe.mapMaybe nonEmptyMap (M.splitRoot m)+{-# INLINE splitRoot #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).+isSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool+isSubmapOf = isSubmapOfBy (==)+{-# INLINE isSubmapOf #-}++-- | /O(m*log(n\/m + 1)), m <= n/.+-- The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if+-- all keys in @t1@ are in tree @t2@, and when @f@ returns 'True' when+-- applied to their respective values. For example, the following+-- expressions are all 'True':+--+-- > isSubmapOfBy (==) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (<=) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (fromList (('a',1) :| [('b',2)]))+--+-- But the following are all 'False':+--+-- > isSubmapOfBy (==) (singleton 'a' 2) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (<) (singleton 'a' 1) (fromList (('a',1) :| [('b',2)]))+-- > isSubmapOfBy (==) (fromList (('a',1) :| [('b',2)])) (singleton 'a' 1)+isSubmapOfBy ::+ Ord k =>+ (a -> b -> Bool) ->+ NEMap k a ->+ NEMap k b ->+ Bool+isSubmapOfBy f (NEMap k v m0) (toMap -> m1) =+ kvSub+ && M.isSubmapOfBy f m0 m1+ where+ kvSub = case M.lookup k m1 of+ Just v0 -> f v v0+ Nothing -> False+{-# INLINE isSubmapOfBy #-}++-- | /O(m*log(n\/m + 1)), m <= n/. Is this a proper submap? (ie. a submap+-- but not equal). Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy'+-- (==)@).+isProperSubmapOf :: (Ord k, Eq a) => NEMap k a -> NEMap k a -> Bool+isProperSubmapOf = isProperSubmapOfBy (==)+{-# INLINE isProperSubmapOf #-}++-- | /O(m*log(n\/m + 1)), m <= n/. 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 values. For+-- example, the following expressions are all 'True':+--+-- > isProperSubmapOfBy (==) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+-- > isProperSubmapOfBy (<=) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+--+-- But the following are all 'False':+--+-- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (fromList ((1,1) :| [(2,2)]))+-- > isProperSubmapOfBy (==) (fromList ((1,1) :| [(2,2)])) (singleton 1 1))+-- > isProperSubmapOfBy (<) (singleton 1 1) (fromList ((1,1) :| [(2,2)]))+isProperSubmapOfBy ::+ Ord k =>+ (a -> b -> Bool) ->+ NEMap k a ->+ NEMap k b ->+ Bool+isProperSubmapOfBy f m1 m2 =+ M.size (nemMap m1) < M.size (nemMap m2)+ && isSubmapOfBy f m1 m2+{-# INLINE isProperSubmapOfBy #-}++-- | /O(log n)/. Lookup the /index/ of a key, which is its zero-based index+-- in the sequence sorted by keys. The index is a number from /0/ up to,+-- but not including, the 'size' of the map.+--+-- > isJust (lookupIndex 2 (fromList ((5,"a") :| [(3,"b")]))) == False+-- > fromJust (lookupIndex 3 (fromList ((5,"a") :| [(3,"b")]))) == 0+-- > fromJust (lookupIndex 5 (fromList ((5,"a") :| [(3,"b")]))) == 1+-- > isJust (lookupIndex 6 (fromList ((5,"a") :| [(3,"b")]))) == False+lookupIndex ::+ Ord k =>+ k ->+ NEMap k a ->+ Maybe Int+lookupIndex k (NEMap k0 _ m) = case compare k k0 of+ LT -> Nothing+ EQ -> Just 0+ GT -> (+ 1) <$> M.lookupIndex k m+{-# INLINE lookupIndex #-}++-- | /O(log n)/. Return the /index/ of a key, which is its zero-based index+-- in the sequence sorted by keys. The index is a number from /0/ up to,+-- but not including, the 'size' of the map. Calls 'error' when the key is+-- not a 'member' of the map.+--+-- > findIndex 2 (fromList ((5,"a") :| [(3,"b")])) Error: element is not in the map+-- > findIndex 3 (fromList ((5,"a") :| [(3,"b")])) == 0+-- > findIndex 5 (fromList ((5,"a") :| [(3,"b")])) == 1+-- > findIndex 6 (fromList ((5,"a") :| [(3,"b")])) Error: element is not in the map+findIndex ::+ Ord k =>+ k ->+ NEMap k a ->+ Int+findIndex k = fromMaybe e . lookupIndex k+ where+ e = error "NEMap.findIndex: element is not in the map"+{-# INLINE findIndex #-}++-- | /O(log n)/. Retrieve an element by its /index/, i.e. by its zero-based+-- index in the sequence sorted by keys. If the /index/ is out of range+-- (less than zero, greater or equal to 'size' of the map), 'error' is+-- called.+--+-- > elemAt 0 (fromList ((5,"a") :| [(3,"b")])) == (3,"b")+-- > elemAt 1 (fromList ((5,"a") :| [(3,"b")])) == (5, "a")+-- > elemAt 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+elemAt ::+ Int ->+ NEMap k a ->+ (k, a)+elemAt 0 (NEMap k v _) = (k, v)+elemAt i (NEMap _ _ m) = M.elemAt (i - 1) m+{-# INLINEABLE elemAt #-}++-- | /O(log n)/. Update the element at /index/, i.e. by its zero-based index in+-- the sequence sorted by keys. If the /index/ is out of range (less than zero,+-- greater or equal to 'size' of the map), 'error' is called.+--+-- Returns a possibly empty map ('Map'), because the function might end up+-- deleting the last key in the map. See 'adjustAt' for a version that+-- disallows deletion, guaranteeing that the result is also a non-empty+-- Map.+--+-- > updateAt (\ _ _ -> Just "x") 0 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "x"), (5, "a")]+-- > updateAt (\ _ _ -> Just "x") 1 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "x")]+-- > updateAt (\ _ _ -> Just "x") 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+-- > updateAt (\ _ _ -> Just "x") (-1) (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+-- > updateAt (\_ _ -> Nothing) 0 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+-- > updateAt (\_ _ -> Nothing) 1 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- > updateAt (\_ _ -> Nothing) 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+-- > updateAt (\_ _ -> Nothing) (-1) (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+updateAt ::+ (k -> a -> Maybe a) ->+ Int ->+ NEMap k a ->+ Map k a+updateAt f 0 (NEMap k v m) = maybe m (flip (insertMinMap k) m) $ f k v+updateAt f i (NEMap k v m) = insertMinMap k v . M.updateAt f (i - 1) $ m+{-# INLINEABLE updateAt #-}++-- | /O(log n)/. Variant of 'updateAt' that disallows deletion. Allows us+-- to guarantee that the result is also a non-empty Map.+adjustAt ::+ (k -> a -> a) ->+ Int ->+ NEMap k a ->+ NEMap k a+adjustAt f 0 (NEMap k0 v m) = NEMap k0 (f k0 v) m+adjustAt f i (NEMap k0 v m) =+ NEMap k0 v+ . M.updateAt (\k -> Just . f k) (i - 1)+ $ m+{-# INLINEABLE adjustAt #-}++-- | /O(log n)/. Delete the element at /index/, i.e. by its zero-based+-- index in the sequence sorted by keys. If the /index/ is out of range+-- (less than zero, greater or equal to 'size' of the map), 'error' is+-- called.+--+-- Returns a potentially empty map ('Map') because of the possibility of+-- deleting the last item in a map.+--+-- > deleteAt 0 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+-- > deleteAt 1 (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+-- > deleteAt 2 (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+-- > deleteAt (-1) (fromList ((5,"a") :| [(3,"b")])) Error: index out of range+deleteAt ::+ Int ->+ NEMap k a ->+ Map k a+deleteAt 0 (NEMap _ _ m) = m+deleteAt i (NEMap k v m) = insertMinMap k v . M.deleteAt (i - 1) $ m+{-# INLINEABLE deleteAt #-}++-- | Take a given number of entries in key order, beginning with the+-- smallest keys.+--+-- Returns a possibly empty map ('Map'), which can only happen if we call+-- @take 0@.+--+-- @+-- take n = Data.Map.fromDistinctAscList . Data.List.NonEmpty.take n . 'toList'+-- @+take ::+ Int ->+ NEMap k a ->+ Map k a+take 0 NEMap{} = M.empty+take i (NEMap k v m) = insertMinMap k v . M.take (i - 1) $ m+{-# INLINEABLE take #-}++-- | Drop a given number of entries in key order, beginning+-- with the smallest keys.+--+-- Returns a possibly empty map ('Map'), in case we drop all of the+-- elements (which can happen if we drop a number greater than or equal to+-- the number of items in the map)+--+-- @+-- drop n = Data.Map.fromDistinctAscList . Data.List.NonEmpty.drop' n . 'toList'+-- @+drop ::+ Int ->+ NEMap k a ->+ Map k a+drop 0 n = toMap n+drop i (NEMap _ _ m) = M.drop (i - 1) m+{-# INLINEABLE drop #-}++-- | /O(log n)/. Split a map at a particular index @i@.+--+-- * @'This' n1@ means that there are less than @i@ items in the map, and+-- @n1@ is the original map.+-- * @'That' n2@ means @i@ was 0; we dropped 0 items, so @n2@ is the+-- original map.+-- * @'These' n1 n2@ gives @n1@ (taking @i@ items from the original map)+-- and @n2@ (dropping @i@ items from the original map))+splitAt ::+ Int ->+ NEMap k a ->+ These (NEMap k a) (NEMap k a)+splitAt 0 n = That n+splitAt i n@(NEMap k v m0) = case (nonEmptyMap m1, nonEmptyMap m2) of+ (Nothing, Nothing) -> This (singleton k v)+ (Just _, Nothing) -> This n+ (Nothing, Just n2) -> These (singleton k v) n2+ (Just _, Just n2) -> These (insertMapMin k v m1) n2+ where+ (m1, m2) = M.splitAt (i - 1) m0+{-# INLINEABLE splitAt #-}++-- | /O(1)/. The minimal key of the map. Note that this is total, making+-- 'Data.Map.lookupMin' obsolete. It is constant-time, so has better+-- asymptotics than @Data.Map.lookupMin@ and @Data.Map.findMin@, as well.+--+-- > findMin (fromList ((5,"a") :| [(3,"b")])) == (3,"b")+findMin :: NEMap k a -> (k, a)+findMin (NEMap k v _) = (k, v)+{-# INLINE findMin #-}++-- | /O(log n)/. The maximal key of the map. Note that this is total, making+-- 'Data.Map.lookupMin' obsolete.+--+-- > findMax (fromList ((5,"a") :| [(3,"b")])) == (5,"a")+findMax :: NEMap k a -> (k, a)+findMax (NEMap k v m) = fromMaybe (k, v) . M.lookupMax $ m+{-# INLINE findMax #-}++-- | /O(1)/. Delete the minimal key. Returns a potentially empty map+-- ('Map'), because we might end up deleting the final key in a singleton+-- map. It is constant-time, so has better asymptotics than+-- 'Data.Map.deleteMin'.+--+-- > deleteMin (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.Map.fromList [(5,"a"), (7,"c")]+-- > deleteMin (singleton 5 "a") == Data.Map.empty+deleteMin :: NEMap k a -> Map k a+deleteMin (NEMap _ _ m) = m+{-# INLINE deleteMin #-}++-- | /O(log n)/. Delete the maximal key. Returns a potentially empty map+-- ('Map'), because we might end up deleting the final key in a singleton+-- map.+--+-- > deleteMax (fromList ((5,"a") :| [(3,"b"), (7,"c")])) == Data.Map.fromList [(3,"b"), (5,"a")]+-- > deleteMax (singleton 5 "a") == Data.Map.empty+deleteMax :: NEMap k a -> Map k a+deleteMax (NEMap k v m) = case M.maxView m of+ Nothing -> M.empty+ Just (_, m') -> insertMinMap k v m'+{-# INLINE deleteMax #-}++-- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the+-- minimal key. Returns a potentially empty map ('Map'), because we might+-- end up deleting the final key in the map if the function returns+-- 'Nothing'. See 'adjustMin' for a version that can guaruntee that we+-- return a non-empty map.+--+-- > updateMin (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "Xb"), (5, "a")]+-- > updateMin (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+updateMin :: (a -> Maybe a) -> NEMap k a -> Map k a+updateMin f = updateMinWithKey (const f)+{-# INLINE updateMin #-}++-- | /O(1)/. A version of 'updateMin' that disallows deletion, allowing us+-- to guarantee that the result is also non-empty.+adjustMin :: (a -> a) -> NEMap k a -> NEMap k a+adjustMin f = adjustMinWithKey (const f)+{-# INLINE adjustMin #-}++-- | /O(1)/ if delete, /O(log n)/ otherwise. Update the value at the+-- minimal key. Returns a potentially empty map ('Map'), because we might+-- end up deleting the final key in the map if the function returns+-- 'Nothing'. See 'adjustMinWithKey' for a version that guaruntees+-- a non-empty map.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+updateMinWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a+updateMinWithKey f (NEMap k v m) = maybe id (insertMinMap k) (f k v) m+{-# INLINE updateMinWithKey #-}++-- | /O(1)/. A version of 'adjustMaxWithKey' that disallows deletion,+-- allowing us to guarantee that the result is also non-empty. Note that+-- it also is able to have better asymptotics than 'updateMinWithKey' in+-- general.+adjustMinWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a+adjustMinWithKey f (NEMap k v m) = NEMap k (f k v) m+{-# INLINE adjustMinWithKey #-}++-- | /O(log n)/. Update the value at the maximal key. Returns+-- a potentially empty map ('Map'), because we might end up deleting the+-- final key in the map if the function returns 'Nothing'. See 'adjustMax'+-- for a version that can guarantee that we return a non-empty map.+--+-- > updateMax (\ a -> Just ("X" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3, "b"), (5, "Xa")]+-- > updateMax (\ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 3 "b"+updateMax :: (a -> Maybe a) -> NEMap k a -> Map k a+updateMax f = updateMaxWithKey (const f)+{-# INLINE updateMax #-}++-- | /O(log n)/. A version of 'updateMax' that disallows deletion, allowing+-- us to guarantee that the result is also non-empty.+adjustMax :: (a -> a) -> NEMap k a -> NEMap k a+adjustMax f = adjustMaxWithKey (const f)+{-# INLINE adjustMax #-}++-- | /O(log n)/. Update the value at the maximal key. Returns+-- a potentially empty map ('Map'), because we might end up deleting the+-- final key in the map if the function returns 'Nothing'. See+-- 'adjustMaxWithKey' for a version that guaruntees a non-empty map.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing) (fromList ((5,"a") :| [(3,"b")])) == Data.Map.singleton 5 "a"+updateMaxWithKey :: (k -> a -> Maybe a) -> NEMap k a -> Map k a+updateMaxWithKey f (NEMap k v m)+ | M.null m = maybe m (M.singleton k) $ f k v+ | otherwise =+ insertMinMap k v+ . M.updateMaxWithKey f+ $ m+{-# INLINE updateMaxWithKey #-}++-- | /O(log n)/. A version of 'updateMaxWithKey' that disallows deletion,+-- allowing us to guarantee that the result is also non-empty.+adjustMaxWithKey :: (k -> a -> a) -> NEMap k a -> NEMap k a+adjustMaxWithKey f (NEMap k0 v m)+ | M.null m = NEMap k0 (f k0 v) m+ | otherwise =+ insertMapMin k0 v+ . M.updateMaxWithKey (\k -> Just . f k)+ $ m+{-# INLINE adjustMaxWithKey #-}++-- | /O(1)/. Retrieves the value associated with minimal key of the+-- map, and the map stripped of that element. It is constant-time, so has+-- better asymptotics than @Data.Map.minView@ for 'Map'.+--+-- Note that unlike @Data.Map.minView@ for 'Map', this cannot ever fail,+-- so doesn't need to return in a 'Maybe'. However, the result 'Map' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > minView (fromList ((5,"a") :| [(3,"b")])) == ("b", Data.Map.singleton 5 "a")+minView :: NEMap k a -> (a, Map k a)+minView = first snd . deleteFindMin+{-# INLINE minView #-}++-- | /O(1)/. Delete and find the minimal key-value pair. It is+-- constant-time, so has better asymptotics that @Data.Map.minView@ for+-- 'Map'.+--+-- Note that unlike @Data.Map.deleteFindMin@ for 'Map', this cannot ever+-- fail, and so is a total function. However, the result 'Map' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > deleteFindMin (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((3,"b"), Data.Map.fromList [(5,"a"), (10,"c")])+deleteFindMin :: NEMap k a -> ((k, a), Map k a)+deleteFindMin (NEMap k v m) = ((k, v), m)+{-# INLINE deleteFindMin #-}++-- | /O(log n)/. Retrieves the value associated with maximal key of the+-- map, and the map stripped of that element.+--+-- Note that unlike @Data.Map.maxView@ from 'Map', this cannot ever fail,+-- so doesn't need to return in a 'Maybe'. However, the result 'Map' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > maxView (fromList ((5,"a") :| [(3,"b")])) == ("a", Data.Map.singleton 3 "b")+maxView :: NEMap k a -> (a, Map k a)+maxView = first snd . deleteFindMax+{-# INLINE maxView #-}++-- | /O(log n)/. Delete and find the minimal key-value pair.+--+-- Note that unlike @Data.Map.deleteFindMax@ for 'Map', this cannot ever+-- fail, and so is a total function. However, the result 'Map' is+-- potentially empty, since the original map might have contained just+-- a single item.+--+-- > deleteFindMax (fromList ((5,"a") :| [(3,"b"), (10,"c")])) == ((10,"c"), Data.Map.fromList [(3,"b"), (5,"a")])+deleteFindMax :: NEMap k a -> ((k, a), Map k a)+deleteFindMax (NEMap k v m) =+ maybe ((k, v), M.empty) (second (insertMinMap k v))+ . M.maxViewWithKey+ $ m+{-# INLINE deleteFindMax #-}++-- | Special property of non-empty maps: The type of non-empty maps over+-- uninhabited keys is itself uninhabited.+--+-- This property also exists for /values/ inside a non-empty container+-- (like for 'NESet', 'NESeq', and 'NEIntMap'); this can be witnessed using+-- the function @'absurd' . 'fold1'@.+--+-- @since 0.3.1.0+absurdNEMap :: NEMap Void a -> b+absurdNEMap = \case {}++-- ---------------------------+-- Combining functions+-- ---------------------------+--+-- Code comes from "Data.Map.Internal" from containers, modified slightly+-- to work with NonEmpty+--+-- Copyright : (c) Daan Leijen 2002+-- (c) Andriy Palamarchuk 2008++combineEq :: Eq a => NonEmpty (a, b) -> NonEmpty (a, b)+combineEq = \case+ x :| [] -> x :| []+ x :| xx@(_ : _) -> go x xx+ where+ go z [] = z :| []+ go z@(kz, _) (x@(kx, xx) : xs')+ | kx == kz = go (kx, xx) xs'+ | otherwise = z NE.<| go x xs'++combineEqWith ::+ Eq a =>+ (a -> b -> b -> b) ->+ NonEmpty (a, b) ->+ NonEmpty (a, b)+combineEqWith f = \case+ x :| [] -> x :| []+ x :| xx@(_ : _) -> go x xx+ where+ go z [] = z :| []+ go z@(kz, zz) (x@(kx, xx) : xs')+ | kx == kz = let yy = f kx xx zz in go (kx, yy) xs'+ | otherwise = z NE.<| go x xs'
+ src/Data/Map/NonEmpty/Strict/Internal.hs view
@@ -0,0 +1,193 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE PatternSynonyms #-}+{-# OPTIONS_HADDOCK not-home #-}++-- |+-- Module : Data.Map.NonEmpty.Strict.Internal+-- Copyright : (c) Justin Le 2018+-- License : BSD3+--+-- Maintainer : justin@jle.im+-- Stability : experimental+-- Portability : non-portable+--+-- Strict internal-use functions used in the implementation of+-- "Data.Map.NonEmpty.Strict". These share the same 'NEMap' type as the+-- lazy modules; only construction is strict in the value.+module Data.Map.NonEmpty.Strict.Internal (+ -- * Non-Empty Map type+ NEMap,+ pattern NEMap,+ nemMap,+ singleton,+ nonEmptyMap,+ withNonEmpty,+ fromList,+ toList,+ map,+ insertWith,+ union,+ unions,+ elems,+ size,+ toMap,++ -- * Folds+ foldr,+ foldr',+ foldr1,+ foldl,+ foldl',+ foldl1,++ -- * Traversals+ traverseWithKey,+ traverseWithKey1,+ foldMapWithKey,++ -- * Unsafe Map Functions+ insertMinMap,+ insertMaxMap,++ -- * Debug+ valid,+) where++import Control.Applicative+import qualified Data.Foldable as F+import Data.Functor.Apply (Apply, MaybeApply (..), (<.>))+import Data.List.NonEmpty (NonEmpty (..))+import Data.Map.Internal (Map (..))+import qualified Data.Map.Internal as MI+import qualified Data.Map.NonEmpty.Lazy.Internal as L+import qualified Data.Map.Strict as M+import Data.Semigroup.Foldable (Foldable1)+import qualified Data.Semigroup.Foldable as F1+import Prelude hiding (Foldable (..), foldl, foldl1, foldr, foldr1, map)++type NEMap = L.NEMap++pattern NEMap :: k -> a -> Map k a -> NEMap k a+pattern NEMap k v m <- L.NEMap k v m+ where+ NEMap k !v m = L.NEMap k v m++{-# COMPLETE NEMap #-}++nemMap :: NEMap k a -> Map k a+nemMap (NEMap _ _ m) = m+{-# INLINE nemMap #-}++singleton :: k -> a -> NEMap k a+singleton k !v = L.NEMap k v M.empty+{-# INLINE singleton #-}++nonEmptyMap :: Map k a -> Maybe (NEMap k a)+nonEmptyMap = L.nonEmptyMap+{-# INLINE nonEmptyMap #-}++withNonEmpty :: b -> (NEMap k a -> b) -> Map k a -> b+withNonEmpty = L.withNonEmpty+{-# INLINE withNonEmpty #-}++fromList :: Ord k => NonEmpty (k, a) -> NEMap k a+fromList ((k, v) :| xs) = F.foldl' (\m (k', v') -> insertWith const k' v' m) (singleton k v) xs+{-# INLINE fromList #-}++toList :: NEMap k a -> NonEmpty (k, a)+toList = L.toList+{-# INLINE toList #-}++map :: (a -> b) -> NEMap k a -> NEMap k b+map f (NEMap k v m) = NEMap k (f v) (M.map f m)+{-# INLINE map #-}++insertWith :: Ord k => (a -> a -> a) -> k -> a -> NEMap k a -> NEMap k a+insertWith f k !v n@(NEMap k0 v0 m) = case compare k k0 of+ LT -> NEMap k v (toMap n)+ EQ -> NEMap k0 (f v v0) m+ GT -> NEMap k0 v0 (M.insertWith f k v m)+{-# INLINE insertWith #-}++union :: Ord k => NEMap k a -> NEMap k a -> NEMap k a+union n1@(NEMap k1 v1 m1) n2@(NEMap k2 v2 m2) = case compare k1 k2 of+ LT -> NEMap k1 v1 . M.union m1 . toMap $ n2+ EQ -> NEMap k1 v1 . M.union m1 $ m2+ GT -> NEMap k2 v2 . M.union (toMap n1) $ m2+{-# INLINE union #-}++unions :: (Foldable1 f, Ord k) => f (NEMap k a) -> NEMap k a+unions ns = case F1.toNonEmpty ns of+ m :| ms -> F.foldl' union m ms+{-# INLINE unions #-}++elems :: NEMap k a -> NonEmpty a+elems = fmap snd . toList+{-# INLINE elems #-}++size :: NEMap k a -> Int+size = L.size+{-# INLINE size #-}++toMap :: NEMap k a -> Map k a+toMap (NEMap k v m) = insertMinMap k v m+{-# INLINE toMap #-}++foldr :: (a -> b -> b) -> b -> NEMap k a -> b+foldr = L.foldr+{-# INLINE foldr #-}++foldr' :: (a -> b -> b) -> b -> NEMap k a -> b+foldr' = L.foldr'+{-# INLINE foldr' #-}++foldr1 :: (a -> a -> a) -> NEMap k a -> a+foldr1 = L.foldr1+{-# INLINE foldr1 #-}++foldl :: (b -> a -> b) -> b -> NEMap k a -> b+foldl = L.foldl+{-# INLINE foldl #-}++foldl' :: (b -> a -> b) -> b -> NEMap k a -> b+foldl' = L.foldl'+{-# INLINE foldl' #-}++foldl1 :: (a -> a -> a) -> NEMap k a -> a+foldl1 = L.foldl1+{-# INLINE foldl1 #-}++traverseWithKey :: Applicative f => (k -> a -> f b) -> NEMap k a -> f (NEMap k b)+traverseWithKey f (NEMap k v m) = NEMap k <$> f k v <*> M.traverseWithKey f m+{-# INLINE traverseWithKey #-}++traverseWithKey1 :: Apply f => (k -> a -> f b) -> NEMap k a -> f (NEMap k b)+traverseWithKey1 f (NEMap k0 v m0) = case runMaybeApply m1 of+ Left m2 -> NEMap k0 <$> f k0 v <.> m2+ Right m2 -> flip (NEMap k0) m2 <$> f k0 v+ where+ m1 = M.traverseWithKey (\k -> MaybeApply . Left . f k) m0+{-# INLINE traverseWithKey1 #-}++foldMapWithKey :: Monoid m => (k -> a -> m) -> NEMap k a -> m+foldMapWithKey = L.foldMapWithKey+{-# INLINE foldMapWithKey #-}++valid :: Ord k => NEMap k a -> Bool+valid (NEMap k _ m) =+ M.valid m+ && all ((k <) . fst . fst) (M.minViewWithKey m)++insertMinMap :: k -> a -> Map k a -> Map k a+insertMinMap kx !x = go+ where+ go Tip = Bin 1 kx x Tip Tip+ go (Bin _ ky y l r) = MI.balanceL ky y (insertMinMap kx x l) r+{-# INLINE insertMinMap #-}++insertMaxMap :: k -> a -> Map k a -> Map k a+insertMaxMap kx !x = go+ where+ go Tip = Bin 1 kx x Tip Tip+ go (Bin _ ky y l r) = MI.balanceR ky y l (insertMaxMap kx x r)+{-# INLINE insertMaxMap #-}
test/Spec.hs view
@@ -2,8 +2,10 @@ -- import Test.Tasty.Ingredients.ConsoleReporter import Test.Tasty import Tests.IntMap+import Tests.IntMap.Strict import Tests.IntSet import Tests.Map+import Tests.Map.Strict import Tests.NonEmptyList import Tests.Sequence import Tests.Set@@ -21,8 +23,10 @@ testGroup "Tests" [ mapTests+ , mapStrictTests , setTests , intMapTests+ , intMapStrictTests , intSetTests , nonEmptyListTests , sequenceTests
test/Tests/IntMap.hs view
@@ -6,7 +6,9 @@ import Control.Applicative import Control.Comonad+import Control.Exception (ErrorCall, evaluate, try) import Data.Coerce+import Data.Either (isLeft) import Data.Foldable import qualified Data.Foldable.WithIndex as IFoldable import Data.Functor.Alt@@ -14,6 +16,8 @@ import qualified Data.Functor.WithIndex as IFunctor import qualified Data.IntMap as M import qualified Data.IntMap.NonEmpty as NEM+import qualified Data.IntMap.NonEmpty.Lazy as NEML+import qualified Data.IntMap.NonEmpty.Strict as NEMS import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as NE import Data.Semigroup.Foldable@@ -35,6 +39,19 @@ prop_valid = property $ assert . NEM.valid =<< forAll neIntMapGen++prop_lazy_singleton_does_not_force_value :: Property+prop_lazy_singleton_does_not_force_value = property $ do+ _ <- evalIO $ evaluate (NEML.singleton 0 (error "forced lazy NEIntMap value" :: Int))+ success++prop_strict_singleton_forces_value :: Property+prop_strict_singleton_forces_value = property $ do+ r <-+ evalIO $+ try @ErrorCall $+ evaluate (NEMS.singleton 0 (error "forced strict NEIntMap value" :: Int))+ assert (isLeft r) -- | We cannot implement these because there is no 'valid' for IntSet -- prop_valid_toMap :: Property
+ test/Tests/IntMap/Strict.hs view
@@ -0,0 +1,1208 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TypeApplications #-}++module Tests.IntMap.Strict (intMapStrictTests) where++import Control.Applicative+import Control.Comonad+import Data.Coerce+import Data.Foldable+import qualified Data.Foldable.WithIndex as IFoldable+import Data.Functor.Alt+import Data.Functor.Identity+import qualified Data.Functor.WithIndex as IFunctor+import qualified Data.IntMap as M+import qualified Data.IntMap.NonEmpty.Lazy as NEML+import qualified Data.IntMap.NonEmpty.Strict as NEM+import qualified Data.IntMap.NonEmpty.Strict as NEMS+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE+import Data.Semigroup.Foldable+import Data.Semigroup.Traversable+import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.Traversable.WithIndex as TWI+import qualified GHC.Exts as Exts+import Hedgehog+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range+import Test.Tasty+import Tests.Util++intMapStrictTests :: TestTree+intMapStrictTests = groupTree $$discover++prop_valid :: Property+prop_valid =+ property $+ assert . NEM.valid =<< forAll neIntMapGen++-- | Pick an existing key out of a generated map, so the branch that+-- actually applies the user function is guaranteed to run.+existingKeyOf :: MonadGen m => NEMS.NEIntMap a -> m NEMS.Key+existingKeyOf = Gen.element . NE.toList . NEMS.keys++prop_lazy_singleton_does_not_force_value :: Property+prop_lazy_singleton_does_not_force_value = property $ do+ k <- forAll intKeyGen+ assertNotForced (NEML.singleton k (error "forced lazy NEIntMap value" :: Text))++prop_strict_singleton_forces_value :: Property+prop_strict_singleton_forces_value = property $ do+ k <- forAll intKeyGen+ assertForced (NEMS.singleton k (error "forced strict NEIntMap value" :: Text))++prop_lazy_insertWith_does_not_force_value :: Property+prop_lazy_insertWith_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $+ NEML.insertWith (\_ _ -> error "forced lazy NEIntMap value") k T.empty m++prop_strict_insertWith_forces_value :: Property+prop_strict_insertWith_forces_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertForced $+ NEMS.insertWith (\_ _ -> error "forced strict NEIntMap value") k T.empty m++prop_lazy_adjustWithKey_does_not_force_value :: Property+prop_lazy_adjustWithKey_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $ NEML.adjustWithKey (\_ _ -> error "forced lazy NEIntMap value") k m++prop_strict_adjustWithKey_forces_value :: Property+prop_strict_adjustWithKey_forces_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertForced $ NEMS.adjustWithKey (\_ _ -> error "forced strict NEIntMap value") k m++prop_lazy_alter_does_not_force_value :: Property+prop_lazy_alter_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $ NEML.alter (const (Just (error "forced lazy NEIntMap value"))) k m++prop_strict_alter_forces_value :: Property+prop_strict_alter_forces_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertForced $ NEMS.alter (const (Just (error "forced strict NEIntMap value"))) k m++prop_lazy_mapWithKey_does_not_force_value :: Property+prop_lazy_mapWithKey_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ assertNotForced $ NEML.mapWithKey (\_ _ -> error "forced lazy NEIntMap value") m++prop_strict_mapWithKey_forces_value :: Property+prop_strict_mapWithKey_forces_value = property $ do+ m <- forAll neIntMapGen+ assertForced $ NEMS.mapWithKey (\_ _ -> error "forced strict NEIntMap value") m++prop_lazy_unionWith_does_not_force_value :: Property+prop_lazy_unionWith_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $+ NEML.unionWith (\_ _ -> error "forced lazy NEIntMap value") m (NEML.singleton k T.empty)++prop_strict_unionWith_forces_value :: Property+prop_strict_unionWith_forces_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertForced $+ NEMS.unionWith (\_ _ -> error "forced strict NEIntMap value") m (NEMS.singleton k T.empty)++prop_lazy_mapMaybeWithKey_does_not_force_value :: Property+prop_lazy_mapMaybeWithKey_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ assertNotForced $ NEML.mapMaybeWithKey (\_ _ -> Just (error "forced lazy NEIntMap value")) m++prop_strict_mapMaybeWithKey_forces_value :: Property+prop_strict_mapMaybeWithKey_forces_value = property $ do+ m <- forAll neIntMapGen+ assertForced $ NEMS.mapMaybeWithKey (\_ _ -> Just (error "forced strict NEIntMap value")) m++prop_lazy_mapAccumWithKey_does_not_force_value :: Property+prop_lazy_mapAccumWithKey_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ assertNotForced $+ snd (NEML.mapAccumWithKey (\acc _ _ -> (acc, error "forced lazy NEIntMap value" :: Text)) () m)++prop_strict_mapAccumWithKey_forces_value :: Property+prop_strict_mapAccumWithKey_forces_value = property $ do+ m <- forAll neIntMapGen+ assertForced $+ snd (NEMS.mapAccumWithKey (\acc _ _ -> (acc, error "forced strict NEIntMap value" :: Text)) () m)++prop_lazy_fromListWith_does_not_force_value :: Property+prop_lazy_fromListWith_does_not_force_value = property $ do+ k <- forAll intKeyGen+ assertNotForced $+ NEML.fromListWith (\_ _ -> error "forced lazy NEIntMap value") ((k, T.empty) :| [(k, T.empty)])++prop_strict_fromListWith_forces_value :: Property+prop_strict_fromListWith_forces_value = property $ do+ k <- forAll intKeyGen+ assertForced $+ NEMS.fromListWith (\_ _ -> error "forced strict NEIntMap value") ((k, T.empty) :| [(k, T.empty)])++prop_lazy_insertMapWith_does_not_force_value :: Property+prop_lazy_insertMapWith_does_not_force_value = property $ do+ k <- forAll intKeyGen+ assertNotForced $+ NEML.insertMapWith (\_ _ -> error "forced lazy NEIntMap value") k T.empty (M.singleton k T.empty)++prop_strict_insertMapWith_forces_value :: Property+prop_strict_insertMapWith_forces_value = property $ do+ k <- forAll intKeyGen+ assertForced $+ NEMS.insertMapWith (\_ _ -> error "forced strict NEIntMap value") k T.empty (M.singleton k T.empty)++prop_lazy_updateWithKey_does_not_force_value :: Property+prop_lazy_updateWithKey_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $ NEML.updateWithKey (\_ _ -> Just (error "forced lazy NEIntMap value")) k m++prop_strict_updateWithKey_forces_value :: Property+prop_strict_updateWithKey_forces_value = property $ do+ m <- forAll neIntMapGen+ k <- forAll (existingKeyOf m)+ assertForced $ NEMS.updateWithKey (\_ _ -> Just (error "forced strict NEIntMap value")) k m++-- | Two-key map with both keys deliberately mapped to the same target key,+-- so the combining function is guaranteed to run.+collidingMapKeysFixture :: MonadGen m => m (NEMS.Key, NEMS.NEIntMap Text)+collidingMapKeysFixture = do+ k <- intKeyGen+ pure (k, NEML.fromList ((k, T.empty) :| [(k + 1, T.empty)]))++prop_lazy_mapKeysWith_does_not_force_value :: Property+prop_lazy_mapKeysWith_does_not_force_value = property $ do+ (k, m) <- forAll collidingMapKeysFixture+ assertNotForced $ NEML.mapKeysWith (\_ _ -> error "forced lazy NEIntMap value") (const k) m++prop_strict_mapKeysWith_forces_value :: Property+prop_strict_mapKeysWith_forces_value = property $ do+ (k, m) <- forAll collidingMapKeysFixture+ assertForced $ NEMS.mapKeysWith (\_ _ -> error "forced strict NEIntMap value") (const k) m++prop_lazy_traverseWithKey_does_not_force_value :: Property+prop_lazy_traverseWithKey_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ assertNotForced $+ runIdentity (NEML.traverseWithKey (\_ _ -> Identity (error "forced lazy NEIntMap value" :: Text)) m)++prop_strict_traverseWithKey_forces_value :: Property+prop_strict_traverseWithKey_forces_value = property $ do+ m <- forAll neIntMapGen+ assertForced $+ runIdentity+ (NEMS.traverseWithKey (\_ _ -> Identity (error "forced strict NEIntMap value" :: Text)) m)++prop_lazy_traverseWithKey1_does_not_force_value :: Property+prop_lazy_traverseWithKey1_does_not_force_value = property $ do+ m <- forAll neIntMapGen+ assertNotForced $+ runIdentity+ (NEML.traverseWithKey1 (\_ _ -> Identity (error "forced lazy NEIntMap value" :: Text)) m)++prop_strict_traverseWithKey1_forces_value :: Property+prop_strict_traverseWithKey1_forces_value = property $ do+ m <- forAll neIntMapGen+ assertForced $+ runIdentity+ (NEMS.traverseWithKey1 (\_ _ -> Identity (error "forced strict NEIntMap value" :: Text)) m)++-- | We cannot implement these because there is no 'valid' for IntSet+-- prop_valid_toMap :: Property+-- prop_valid_toMap = property $+-- assert . M.valid . NEM.toMap =<< forAll neIntMapGen++-- prop_valid_insertMinIntMap :: Property+-- prop_valid_insertMinIntMap = property $ do+-- n <- forAll $ do+-- m <- intMapGen+-- let k = maybe 0 (subtract 1 . fst) $ M.lookupMin m+-- v <- valGen+-- pure $ NEM.insertMinIntMap k v m+-- assert $ M.valid n++-- prop_valid_insertMaxIntMap :: Property+-- prop_valid_insertMaxIntMap = property $ do+-- n <- forAll $ do+-- m <- intMapGen+-- let k = maybe 0 ((+ 1) . fst) $ M.lookupMax m+-- v <- valGen+-- pure $ NEM.insertMaxIntMap k v m+-- assert $ M.valid n++prop_valid_insertMapMin :: Property+prop_valid_insertMapMin = property $ do+ n <- forAll $ do+ m <- intMapGen+ let k = maybe 0 (subtract 1 . fst) $ M.lookupMin m+ v <- valGen+ pure $ NEM.insertMapMin k v m+ assert $ NEM.valid n++prop_valid_insertMapMax :: Property+prop_valid_insertMapMax = property $ do+ n <- forAll $ do+ m <- intMapGen+ let k = maybe 0 ((+ 1) . fst) $ M.lookupMax m+ v <- valGen+ pure $ NEM.insertMapMax k v m+ assert $ NEM.valid n++prop_toMapIso1 :: Property+prop_toMapIso1 = property $ do+ m0 <- forAll intMapGen+ tripping+ m0+ NEM.nonEmptyMap+ (Identity . maybe M.empty NEM.toMap)++prop_toMapIso2 :: Property+prop_toMapIso2 = property $ do+ m0 <- forAll $ Gen.maybe neIntMapGen+ tripping+ m0+ (maybe M.empty NEM.toMap)+ (Identity . NEM.nonEmptyMap)++prop_read_show :: Property+prop_read_show = readShow neIntMapGen++prop_read1_show1 :: Property+prop_read1_show1 = readShow1 neIntMapGen++prop_show_show1 :: Property+prop_show_show1 = showShow1 neIntMapGen++prop_splitRoot :: Property+prop_splitRoot = property $ do+ n <- forAll neIntMapGen+ let rs = NEM.splitRoot n+ allItems = foldMap1 NEM.keys rs+ n' = NEM.unions rs+ assert $ ascending allItems+ mapM_ (assert . (`NEM.isSubmapOf` n)) rs+ length allItems === length n'+ n === n'+ where+ ascending (x :| xs) = case NE.nonEmpty xs of+ Nothing -> True+ Just ys@(y :| _) -> x < y && ascending ys++prop_functorWithIndex :: Property+prop_functorWithIndex =+ property $ do+ m <- forAll neIntMapGen+ let f k v = v <> T.pack (show k)+ IFunctor.imap f m === NEM.mapWithKey f m++prop_foldableWithIndex :: Property+prop_foldableWithIndex =+ property $ do+ m <- forAll neIntMapGen+ IFoldable.ifoldMap (\k v -> [(k, v)]) m === toList (NEM.toList m)++prop_traversableWithIndex :: Property+prop_traversableWithIndex =+ property $ do+ m <- forAll neIntMapGen+ let f k v = v <> T.pack (show k)+ TWI.itraverse (\k v -> Identity (f k v)) m === Identity (NEM.mapWithKey f m)+ TWI.itraverse (\k v -> Const [(k, v)]) m === Const (toList (NEM.toList m))++prop_extract_duplicate :: Property+prop_extract_duplicate = property $ do+ n <- forAll neIntMapGen+ tripping+ n+ duplicate+ (Identity . extract)++prop_fmap_extract_duplicate :: Property+prop_fmap_extract_duplicate = property $ do+ n <- forAll neIntMapGen+ tripping+ n+ duplicate+ (Identity . fmap extract)++prop_duplicate_duplicate :: Property+prop_duplicate_duplicate = property $ do+ n <- forAll neIntMapGen+ let dd1 = duplicate . duplicate $ n+ dd2 = fmap duplicate . duplicate $ n+ assert $ NEM.valid dd1+ assert $ NEM.valid dd2+ dd1 === dd2++prop_insertMapWithKey :: Property+prop_insertMapWithKey =+ ttProp+ (gf3 valGen :?> GTIntKey :-> GTVal :-> GTIntMap :-> TTNEIntMap)+ M.insertWithKey+ NEM.insertMapWithKey++prop_singleton :: Property+prop_singleton =+ ttProp+ (GTIntKey :-> GTVal :-> TTNEIntMap)+ M.singleton+ NEM.singleton++prop_fromSet :: Property+prop_fromSet =+ ttProp+ (gf1 valGen :?> GTNEIntSet :-> TTNEIntMap)+ M.fromSet+ NEM.fromSet++prop_fromAscList :: Property+prop_fromAscList =+ ttProp+ (GTSorted STAsc (GTNEList Nothing (GTIntKey :&: GTVal)) :-> TTNEIntMap)+ M.fromAscList+ NEM.fromAscList++prop_fromAscListWithKey :: Property+prop_fromAscListWithKey =+ ttProp+ (gf3 valGen :?> GTSorted STAsc (GTNEList Nothing (GTIntKey :&: GTVal)) :-> TTNEIntMap)+ M.fromAscListWithKey+ NEM.fromAscListWithKey++prop_fromDistinctAscList :: Property+prop_fromDistinctAscList =+ ttProp+ (GTSorted STDistinctAsc (GTNEList Nothing (GTIntKey :&: GTVal)) :-> TTNEIntMap)+ M.fromDistinctAscList+ NEM.fromDistinctAscList++prop_fromListWithKey :: Property+prop_fromListWithKey =+ ttProp+ (gf3 valGen :?> GTNEList Nothing (GTIntKey :&: GTVal) :-> TTNEIntMap)+ M.fromListWithKey+ NEM.fromListWithKey++prop_toFromOverloadedList :: Property+prop_toFromOverloadedList =+ property $ do+ s <- forAll neIntMapGen+ s === Exts.fromList (Exts.toList s)++prop_fromToOverloadedList :: Property+prop_fromToOverloadedList =+ property $ do+ l <- forAll neIntTextListUniqGen+ l === Exts.toList (Exts.fromList @(NEM.NEIntMap Text) l)++prop_insert :: Property+prop_insert =+ ttProp+ (GTIntKey :-> GTVal :-> GTNEIntMap :-> TTNEIntMap)+ M.insert+ NEM.insert++prop_insertWithKey :: Property+prop_insertWithKey =+ ttProp+ (gf3 valGen :?> GTIntKey :-> GTVal :-> GTNEIntMap :-> TTNEIntMap)+ M.insertWithKey+ NEM.insertWithKey++prop_delete :: Property+prop_delete =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTOther)+ M.delete+ NEM.delete++prop_deleteMaybe :: Property+prop_deleteMaybe =+ property $ do+ k <- forAll intKeyGen+ m <- forAll neIntMapGen+ NEM.deleteMaybe k m === NEM.nonEmptyMap (M.delete k (NEM.toMap m))++prop_adjustWithKey :: Property+prop_adjustWithKey =+ ttProp+ (gf2 valGen :?> GTIntKey :-> GTNEIntMap :-> TTNEIntMap)+ M.adjustWithKey+ NEM.adjustWithKey++prop_updateWithKey :: Property+prop_updateWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTIntKey :-> GTNEIntMap :-> TTOther)+ M.updateWithKey+ NEM.updateWithKey++prop_updateLookupWithKey :: Property+prop_updateLookupWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTIntKey :-> GTNEIntMap :-> TTMaybe TTVal :*: TTOther)+ M.updateLookupWithKey+ NEM.updateLookupWithKey++prop_alter :: Property+prop_alter =+ ttProp+ (gf1 (Gen.maybe valGen) :?> GTIntKey :-> GTNEIntMap :-> TTOther)+ M.alter+ NEM.alter++prop_alter' :: Property+prop_alter' =+ ttProp+ (gf1 valGen :?> GTIntKey :-> GTNEIntMap :-> TTNEIntMap)+ (M.alter . fmap Just)+ NEM.alter'++prop_alterF :: Property+prop_alterF =+ ttProp+ ( gf1 (Gen.maybe valGen)+ :?> GTIntKey+ :-> GTNEIntMap+ :-> TTCtx (GTMaybe GTVal :-> TTOther) (TTMaybe TTVal)+ )+ (M.alterF . Context)+ (NEM.alterF . Context)++prop_alterF_rules_Const :: Property+prop_alterF_rules_Const =+ ttProp+ ( gf1 (Const <$> valGen)+ :?> GTIntKey+ :-> GTNEIntMap+ :-> TTOther+ )+ (\f k m -> getConst (M.alterF f k m))+ (\f k m -> getConst (NEM.alterF f k m))++prop_alterF_rules_Identity :: Property+prop_alterF_rules_Identity =+ ttProp+ ( gf1 (Identity <$> Gen.maybe valGen)+ :?> GTIntKey+ :-> GTNEIntMap+ :-> TTOther+ )+ (\f k m -> runIdentity (M.alterF f k m))+ (\f k m -> runIdentity (NEM.alterF f k m))++prop_alterF' :: Property+prop_alterF' =+ ttProp+ (gf1 valGen :?> GTIntKey :-> GTNEIntMap :-> TTCtx (GTVal :-> TTNEIntMap) (TTMaybe TTVal))+ (M.alterF . Context . fmap Just)+ (NEM.alterF' . Context)++prop_alterF'_rules_Const :: Property+prop_alterF'_rules_Const =+ ttProp+ ( gf1 (Const <$> valGen)+ :?> GTIntKey+ :-> GTNEIntMap+ :-> TTOther+ )+ (\f k m -> let f' = fmap Just . f in getConst (M.alterF f' k m))+ (\f k m -> getConst (NEM.alterF' f k m))++-- -- | This fails, but isn't possible to fix without copying-and-pasting more+-- -- in code from containers.+-- prop_alterF'_rules_Identity :: Property+-- prop_alterF'_rules_Identity = ttProp ( gf1 (Identity <$> valGen)+-- :?> GTIntKey+-- :-> GTNEIntMap+-- :-> TTNEIntMap+-- )+-- (\f k m -> let f' = fmap Just . f in runIdentity (M.alterF f' k m))+-- (\f k m -> runIdentity (NEM.alterF' f k m))++prop_lookup :: Property+prop_lookup =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTMaybe TTVal)+ M.lookup+ NEM.lookup++prop_findWithDefault :: Property+prop_findWithDefault =+ ttProp+ (GTVal :-> GTIntKey :-> GTNEIntMap :-> TTVal)+ M.findWithDefault+ NEM.findWithDefault++prop_member :: Property+prop_member =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTOther)+ M.member+ NEM.member++prop_notMember :: Property+prop_notMember =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTOther)+ M.notMember+ NEM.notMember++prop_lookupLT :: Property+prop_lookupLT =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTMaybe (TTOther :*: TTVal))+ M.lookupLT+ NEM.lookupLT++prop_lookupGT :: Property+prop_lookupGT =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTMaybe (TTOther :*: TTVal))+ M.lookupGT+ NEM.lookupGT++prop_lookupLE :: Property+prop_lookupLE =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTMaybe (TTOther :*: TTVal))+ M.lookupLE+ NEM.lookupLE++prop_lookupGE :: Property+prop_lookupGE =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTMaybe (TTOther :*: TTVal))+ M.lookupGE+ NEM.lookupGE++prop_size :: Property+prop_size =+ ttProp+ (GTNEIntMap :-> TTOther)+ M.size+ NEM.size++prop_union :: Property+prop_union =+ ttProp+ (GTNEIntMap :-> GTNEIntMap :-> TTNEIntMap)+ M.union+ NEM.union++prop_unionMapLeft :: Property+prop_unionMapLeft =+ ttProp+ (GTIntMap :-> GTNEIntMap :-> TTNEIntMap)+ M.union+ NEM.unionMapLeft++prop_unionMapRight :: Property+prop_unionMapRight =+ ttProp+ (GTNEIntMap :-> GTIntMap :-> TTNEIntMap)+ M.union+ NEM.unionMapRight++prop_unionWith :: Property+prop_unionWith =+ ttProp+ (gf2 valGen :?> GTNEIntMap :-> GTNEIntMap :-> TTNEIntMap)+ M.unionWith+ NEM.unionWith++prop_unionMapWithLeft :: Property+prop_unionMapWithLeft =+ ttProp+ (gf2 valGen :?> GTIntMap :-> GTNEIntMap :-> TTNEIntMap)+ M.unionWith+ NEM.unionMapWithLeft++prop_unionMapWithRight :: Property+prop_unionMapWithRight =+ ttProp+ (gf2 valGen :?> GTNEIntMap :-> GTIntMap :-> TTNEIntMap)+ M.unionWith+ NEM.unionMapWithRight++prop_unionWithKey :: Property+prop_unionWithKey =+ ttProp+ (gf3 valGen :?> GTNEIntMap :-> GTNEIntMap :-> TTNEIntMap)+ M.unionWithKey+ NEM.unionWithKey++prop_unionMapWithKeyLeft :: Property+prop_unionMapWithKeyLeft =+ ttProp+ (gf3 valGen :?> GTIntMap :-> GTNEIntMap :-> TTNEIntMap)+ M.unionWithKey+ NEM.unionMapWithKeyLeft++prop_unionMapWithKeyRight :: Property+prop_unionMapWithKeyRight =+ ttProp+ (gf3 valGen :?> GTNEIntMap :-> GTIntMap :-> TTNEIntMap)+ M.unionWithKey+ NEM.unionMapWithKeyRight++prop_unions :: Property+prop_unions =+ ttProp+ (GTNEList (Just (Range.linear 2 5)) GTNEIntMap :-> TTNEIntMap)+ M.unions+ NEM.unions++prop_unionsWith :: Property+prop_unionsWith =+ ttProp+ (gf2 valGen :?> GTNEList (Just (Range.linear 2 5)) GTNEIntMap :-> TTNEIntMap)+ M.unionsWith+ NEM.unionsWith++prop_difference :: Property+prop_difference =+ ttProp+ (GTNEIntMap :-> GTNEIntMap :-> TTOther)+ M.difference+ NEM.difference++prop_differenceWithKey :: Property+prop_differenceWithKey =+ ttProp+ (gf3 (Gen.maybe valGen) :?> GTNEIntMap :-> GTNEIntMap :-> TTOther)+ M.differenceWithKey+ NEM.differenceWithKey++prop_intersection :: Property+prop_intersection =+ ttProp+ (GTNEIntMap :-> GTNEIntMap :-> TTOther)+ M.intersection+ NEM.intersection++prop_intersectionWithKey :: Property+prop_intersectionWithKey =+ ttProp+ (gf3 valGen :?> GTNEIntMap :-> GTNEIntMap :-> TTOther)+ M.intersectionWithKey+ NEM.intersectionWithKey++prop_map :: Property+prop_map =+ ttProp+ (gf1 valGen :?> GTNEIntMap :-> TTNEIntMap)+ M.map+ NEM.map++prop_map_rules_map :: Property+prop_map_rules_map =+ ttProp+ (gf1 valGen :?> gf1 valGen :?> GTNEIntMap :-> TTNEIntMap)+ (\f g xs -> M.map f (M.map g xs))+ (\f g xs -> NEM.map f (NEM.map g xs))++prop_map_rules_coerce :: Property+prop_map_rules_coerce =+ ttProp+ (GTNEIntMap :-> TTNEIntMap)+ (M.map @Text @Text coerce)+ (NEM.map @Text @Text coerce)++prop_map_rules_mapWithKey :: Property+prop_map_rules_mapWithKey =+ ttProp+ (gf1 valGen :?> gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)+ (\f g xs -> M.map f (M.mapWithKey g xs))+ (\f g xs -> NEM.map f (NEM.mapWithKey g xs))++prop_mapWithKey :: Property+prop_mapWithKey =+ ttProp+ (gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)+ M.mapWithKey+ NEM.mapWithKey++prop_mapWithKey_rules_mapWithKey :: Property+prop_mapWithKey_rules_mapWithKey =+ ttProp+ (gf2 valGen :?> gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)+ (\f g xs -> M.mapWithKey f (M.mapWithKey g xs))+ (\f g xs -> NEM.mapWithKey f (NEM.mapWithKey g xs))++prop_mapWithKey_rules_map :: Property+prop_mapWithKey_rules_map =+ ttProp+ (gf2 valGen :?> gf1 valGen :?> GTNEIntMap :-> TTNEIntMap)+ (\f g xs -> M.mapWithKey f (M.map g xs))+ (\f g xs -> NEM.mapWithKey f (NEM.map g xs))++prop_traverseWithKey1 :: Property+prop_traverseWithKey1 =+ ttProp+ (gf1 valGen :?> GTNEIntMap :-> TTBazaar GTVal TTNEIntMap TTVal)+ (\f -> M.traverseWithKey (\k -> (`More` Done (f . (k,)))))+ (\f -> NEM.traverseWithKey1 (\k -> (`More` Done (f . (k,)))))++prop_traverseWithKey :: Property+prop_traverseWithKey =+ ttProp+ (gf1 valGen :?> GTNEIntMap :-> TTBazaar GTVal TTNEIntMap TTVal)+ (\f -> M.traverseWithKey (\k -> (`More` Done (f . (k,)))))+ (\f -> NEM.traverseWithKey (\k -> (`More` Done (f . (k,)))))++prop_sequence1 :: Property+prop_sequence1 =+ ttProp+ (GTNEIntMap :-> TTBazaar GTVal TTNEIntMap TTVal)+ (traverse (`More` Done id))+ (traverse1 (`More` Done id))++prop_sequenceA :: Property+prop_sequenceA =+ ttProp+ (GTNEIntMap :-> TTBazaar GTVal TTNEIntMap TTVal)+ (traverse (`More` Done id))+ (traverse (`More` Done id))++prop_mapAccumWithKey :: Property+prop_mapAccumWithKey =+ ttProp+ ( gf3 ((,) <$> valGen <*> valGen)+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ :*: TTNEIntMap+ )+ M.mapAccumWithKey+ NEM.mapAccumWithKey++prop_mapAccumRWithKey :: Property+prop_mapAccumRWithKey =+ ttProp+ ( gf3 ((,) <$> valGen <*> valGen)+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ :*: TTNEIntMap+ )+ M.mapAccumRWithKey+ NEM.mapAccumRWithKey++prop_mapKeys :: Property+prop_mapKeys =+ ttProp+ (gf1 intKeyGen :?> GTNEIntMap :-> TTNEIntMap)+ M.mapKeys+ NEM.mapKeys++prop_mapKeysWith :: Property+prop_mapKeysWith =+ ttProp+ ( gf2 valGen+ :?> gf1 intKeyGen+ :?> GTNEIntMap+ :-> TTNEIntMap+ )+ M.mapKeysWith+ NEM.mapKeysWith++prop_mapKeysMonotonic :: Property+prop_mapKeysMonotonic =+ ttProp+ (GTNEIntMap :-> TTNEIntMap)+ (M.mapKeysMonotonic (* 2))+ (NEM.mapKeysMonotonic (* 2))++prop_foldr :: Property+prop_foldr =+ ttProp+ ( gf2 valGen+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ )+ M.foldr+ NEM.foldr++prop_foldl :: Property+prop_foldl =+ ttProp+ ( gf2 valGen+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ )+ M.foldl+ NEM.foldl++prop_foldr1 :: Property+prop_foldr1 =+ ttProp+ ( gf2 valGen+ :?> GTNEIntMap+ :-> TTOther+ )+ foldr1+ NEM.foldr1++prop_foldl1 :: Property+prop_foldl1 =+ ttProp+ ( gf2 valGen+ :?> GTNEIntMap+ :-> TTOther+ )+ foldl1+ NEM.foldl1++prop_foldrWithKey :: Property+prop_foldrWithKey =+ ttProp+ ( gf3 valGen+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ )+ M.foldrWithKey+ NEM.foldrWithKey++prop_foldlWithKey :: Property+prop_foldlWithKey =+ ttProp+ ( gf3 valGen+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ )+ M.foldlWithKey+ NEM.foldlWithKey++prop_foldMapWithKey :: Property+prop_foldMapWithKey =+ ttProp+ (gf2 valGen :?> GTNEIntMap :-> TTOther)+ (\f -> foldMap (uncurry f) . M.toList)+ NEM.foldMapWithKey++prop_foldr' :: Property+prop_foldr' =+ ttProp+ ( gf2 valGen+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ )+ M.foldr'+ NEM.foldr'++prop_foldl' :: Property+prop_foldl' =+ ttProp+ ( gf2 valGen+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ )+ M.foldl'+ NEM.foldl'++prop_foldr1' :: Property+prop_foldr1' =+ ttProp+ ( gf2 valGen+ :?> GTNEIntMap+ :-> TTOther+ )+ foldr1+ NEM.foldr1'++prop_foldl1' :: Property+prop_foldl1' =+ ttProp+ ( gf2 valGen+ :?> GTNEIntMap+ :-> TTOther+ )+ foldl1+ NEM.foldl1'++prop_foldrWithKey' :: Property+prop_foldrWithKey' =+ ttProp+ ( gf3 valGen+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ )+ M.foldrWithKey'+ NEM.foldrWithKey'++prop_foldlWithKey' :: Property+prop_foldlWithKey' =+ ttProp+ ( gf3 valGen+ :?> GTOther valGen+ :-> GTNEIntMap+ :-> TTOther+ )+ M.foldlWithKey'+ NEM.foldlWithKey'++prop_elems :: Property+prop_elems =+ ttProp+ (GTNEIntMap :-> TTNEList TTVal)+ M.elems+ NEM.elems++prop_keys :: Property+prop_keys =+ ttProp+ (GTNEIntMap :-> TTNEList TTOther)+ M.keys+ NEM.keys++prop_assocs :: Property+prop_assocs =+ ttProp+ (GTNEIntMap :-> TTNEList (TTOther :*: TTVal))+ M.assocs+ NEM.assocs++prop_keysSet :: Property+prop_keysSet =+ ttProp+ (GTNEIntMap :-> TTNEIntSet)+ M.keysSet+ NEM.keysSet++prop_toList :: Property+prop_toList =+ ttProp+ (GTNEIntMap :-> TTNEList (TTOther :*: TTVal))+ M.toList+ NEM.toList++prop_toDescList :: Property+prop_toDescList =+ ttProp+ (GTNEIntMap :-> TTNEList (TTOther :*: TTVal))+ M.toDescList+ NEM.toDescList++prop_filter :: Property+prop_filter =+ ttProp+ (gf1 Gen.bool :?> GTNEIntMap :-> TTOther)+ M.filter+ NEM.filter++prop_filterWithKey :: Property+prop_filterWithKey =+ ttProp+ (gf2 Gen.bool :?> GTNEIntMap :-> TTOther)+ M.filterWithKey+ NEM.filterWithKey++prop_restrictKeys :: Property+prop_restrictKeys =+ ttProp+ (GTNEIntMap :-> GTIntSet :-> TTOther)+ M.restrictKeys+ NEM.restrictKeys++prop_withoutKeys :: Property+prop_withoutKeys =+ ttProp+ (GTNEIntMap :-> GTIntSet :-> TTOther)+ M.withoutKeys+ NEM.withoutKeys++prop_partitionWithKey :: Property+prop_partitionWithKey =+ ttProp+ (gf2 Gen.bool :?> GTNEIntMap :-> TTThese TTNEIntMap TTNEIntMap)+ M.partitionWithKey+ NEM.partitionWithKey++prop_mapMaybeWithKey :: Property+prop_mapMaybeWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTNEIntMap :-> TTOther)+ M.mapMaybeWithKey+ NEM.mapMaybeWithKey++prop_mapEitherWithKey :: Property+prop_mapEitherWithKey =+ ttProp+ ( gf2 (Gen.choice [Left <$> valGen, Right <$> valGen])+ :?> GTNEIntMap+ :-> TTThese TTNEIntMap TTNEIntMap+ )+ M.mapEitherWithKey+ NEM.mapEitherWithKey++prop_split :: Property+prop_split =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTMThese TTNEIntMap TTNEIntMap)+ M.split+ NEM.split++prop_splitLookup :: Property+prop_splitLookup =+ ttProp+ (GTIntKey :-> GTNEIntMap :-> TTTThese TTVal TTNEIntMap TTNEIntMap)+ (\k -> (\(x, y, z) -> (y, x, z)) . M.splitLookup k)+ NEM.splitLookup++prop_isSubmapOfBy :: Property+prop_isSubmapOfBy =+ ttProp+ (gf2 Gen.bool :?> GTNEIntMap :-> GTNEIntMap :-> TTOther)+ M.isSubmapOfBy+ NEM.isSubmapOfBy++prop_isProperSubmapOfBy :: Property+prop_isProperSubmapOfBy =+ ttProp+ (gf2 Gen.bool :?> GTNEIntMap :-> GTNEIntMap :-> TTOther)+ M.isProperSubmapOfBy+ NEM.isProperSubmapOfBy++prop_findMin :: Property+prop_findMin =+ ttProp+ (GTNEIntMap :-> TTOther :*: TTVal)+ M.findMin+ NEM.findMin++prop_findMax :: Property+prop_findMax =+ ttProp+ (GTNEIntMap :-> TTOther :*: TTVal)+ M.findMax+ NEM.findMax++prop_deleteMin :: Property+prop_deleteMin =+ ttProp+ (GTNEIntMap :-> TTOther)+ M.deleteMin+ NEM.deleteMin++prop_deleteMax :: Property+prop_deleteMax =+ ttProp+ (GTNEIntMap :-> TTOther)+ M.deleteMax+ NEM.deleteMax++prop_deleteFindMin :: Property+prop_deleteFindMin =+ ttProp+ (GTNEIntMap :-> (TTOther :*: TTVal) :*: TTOther)+ M.deleteFindMin+ NEM.deleteFindMin++prop_deleteFindMax :: Property+prop_deleteFindMax =+ ttProp+ (GTNEIntMap :-> (TTOther :*: TTVal) :*: TTOther)+ M.deleteFindMax+ NEM.deleteFindMax++prop_updateMinWithKey :: Property+prop_updateMinWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTNEIntMap :-> TTOther)+ M.updateMinWithKey+ NEM.updateMinWithKey++prop_updateMaxWithKey :: Property+prop_updateMaxWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTNEIntMap :-> TTOther)+ M.updateMaxWithKey+ NEM.updateMaxWithKey++prop_adjustMinWithKey :: Property+prop_adjustMinWithKey =+ ttProp+ (gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)+ (M.updateMinWithKey . (fmap . fmap) Just)+ NEM.adjustMinWithKey++prop_adjustMaxWithKey :: Property+prop_adjustMaxWithKey =+ ttProp+ (gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)+ (M.updateMaxWithKey . (fmap . fmap) Just)+ NEM.adjustMaxWithKey++prop_minView :: Property+prop_minView =+ ttProp+ (GTNEIntMap :-> TTMaybe (TTVal :*: TTOther))+ M.minView+ (Just . NEM.minView)++prop_maxView :: Property+prop_maxView =+ ttProp+ (GTNEIntMap :-> TTMaybe (TTVal :*: TTOther))+ M.maxView+ (Just . NEM.maxView)++prop_elem :: Property+prop_elem =+ ttProp+ (GTVal :-> GTNEIntMap :-> TTOther)+ elem+ elem++prop_fold1 :: Property+prop_fold1 =+ ttProp+ (GTNEIntMap :-> TTVal)+ fold+ fold1++prop_fold :: Property+prop_fold =+ ttProp+ (GTNEIntMap :-> TTVal)+ fold+ fold++prop_foldMap1 :: Property+prop_foldMap1 =+ ttProp+ (gf1 valGen :?> GTNEIntMap :-> TTOther)+ (\f -> foldMap ((: []) . f))+ (\f -> foldMap1 ((: []) . f))++prop_foldMap :: Property+prop_foldMap =+ ttProp+ (gf1 valGen :?> GTNEIntMap :-> TTOther)+ (\f -> foldMap ((: []) . f))+ (\f -> foldMap ((: []) . f))++prop_alt :: Property+prop_alt =+ ttProp+ (GTNEIntMap :-> GTNEIntMap :-> TTNEIntMap)+ (<!>)+ (<!>)
test/Tests/Map.hs view
@@ -5,7 +5,9 @@ import Control.Applicative import Control.Comonad+import Control.Exception (ErrorCall, evaluate, try) import Data.Coerce+import Data.Either (isLeft) import Data.Foldable import qualified Data.Foldable.WithIndex as IFoldable import Data.Functor.Alt@@ -16,6 +18,8 @@ import qualified Data.Map as M import qualified Data.Map.NonEmpty as NEM import qualified Data.Map.NonEmpty.Internal as NEM+import qualified Data.Map.NonEmpty.Lazy as NEML+import qualified Data.Map.NonEmpty.Strict as NEMS import Data.Semigroup.Foldable import Data.Semigroup.Traversable import Data.Text (Text)@@ -35,6 +39,19 @@ prop_valid = property $ assert . NEM.valid =<< forAll neMapGen++prop_lazy_singleton_does_not_force_value :: Property+prop_lazy_singleton_does_not_force_value = property $ do+ _ <- evalIO $ evaluate (NEML.singleton dummyKey (error "forced lazy NEMap value" :: Int))+ success++prop_strict_singleton_forces_value :: Property+prop_strict_singleton_forces_value = property $ do+ r <-+ evalIO $+ try @ErrorCall $+ evaluate (NEMS.singleton dummyKey (error "forced strict NEMap value" :: Int))+ assert (isLeft r) prop_valid_toMap :: Property prop_valid_toMap =
+ test/Tests/Map/Strict.hs view
@@ -0,0 +1,1338 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeApplications #-}++module Tests.Map.Strict (mapStrictTests) where++import Control.Applicative+import Control.Comonad+import Data.Coerce+import Data.Foldable+import qualified Data.Foldable.WithIndex as IFoldable+import Data.Functor.Alt+import Data.Functor.Identity+import qualified Data.Functor.WithIndex as IFunctor+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE+import qualified Data.Map as M+import qualified Data.Map.NonEmpty.Lazy as NEML+import qualified Data.Map.NonEmpty.Strict as NEM+import qualified Data.Map.NonEmpty.Strict as NEMS+import qualified Data.Map.NonEmpty.Strict.Internal as NEM+import Data.Semigroup.Foldable+import Data.Semigroup.Traversable+import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.Traversable.WithIndex as TWI+import qualified GHC.Exts as Exts+import Hedgehog+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range+import Test.Tasty+import Tests.Util++mapStrictTests :: TestTree+mapStrictTests = groupTree $$discover++prop_valid :: Property+prop_valid =+ property $+ assert . NEM.valid =<< forAll neMapGen++-- | Pick an existing key out of a generated map, so the branch that+-- actually applies the user function is guaranteed to run.+existingKeyOf :: MonadGen m => NEMS.NEMap KeyType a -> m KeyType+existingKeyOf = Gen.element . NE.toList . NEMS.keys++prop_lazy_singleton_does_not_force_value :: Property+prop_lazy_singleton_does_not_force_value = property $ do+ k <- forAll keyGen+ assertNotForced (NEML.singleton k (error "forced lazy NEMap value" :: Text))++prop_strict_singleton_forces_value :: Property+prop_strict_singleton_forces_value = property $ do+ k <- forAll keyGen+ assertForced (NEMS.singleton k (error "forced strict NEMap value" :: Text))++prop_lazy_insertWith_does_not_force_value :: Property+prop_lazy_insertWith_does_not_force_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $+ NEML.insertWith (\_ _ -> error "forced lazy NEMap value") k T.empty m++prop_strict_insertWith_forces_value :: Property+prop_strict_insertWith_forces_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertForced $+ NEMS.insertWith (\_ _ -> error "forced strict NEMap value") k T.empty m++prop_lazy_adjustWithKey_does_not_force_value :: Property+prop_lazy_adjustWithKey_does_not_force_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $ NEML.adjustWithKey (\_ _ -> error "forced lazy NEMap value") k m++prop_strict_adjustWithKey_forces_value :: Property+prop_strict_adjustWithKey_forces_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertForced $ NEMS.adjustWithKey (\_ _ -> error "forced strict NEMap value") k m++prop_lazy_alter_does_not_force_value :: Property+prop_lazy_alter_does_not_force_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $ NEML.alter (const (Just (error "forced lazy NEMap value"))) k m++prop_strict_alter_forces_value :: Property+prop_strict_alter_forces_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertForced $ NEMS.alter (const (Just (error "forced strict NEMap value"))) k m++prop_lazy_mapWithKey_does_not_force_value :: Property+prop_lazy_mapWithKey_does_not_force_value = property $ do+ m <- forAll neMapGen+ assertNotForced $ NEML.mapWithKey (\_ _ -> error "forced lazy NEMap value") m++prop_strict_mapWithKey_forces_value :: Property+prop_strict_mapWithKey_forces_value = property $ do+ m <- forAll neMapGen+ assertForced $ NEMS.mapWithKey (\_ _ -> error "forced strict NEMap value") m++prop_lazy_unionWith_does_not_force_value :: Property+prop_lazy_unionWith_does_not_force_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $+ NEML.unionWith (\_ _ -> error "forced lazy NEMap value") m (NEML.singleton k T.empty)++prop_strict_unionWith_forces_value :: Property+prop_strict_unionWith_forces_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertForced $+ NEMS.unionWith (\_ _ -> error "forced strict NEMap value") m (NEMS.singleton k T.empty)++prop_lazy_mapMaybeWithKey_does_not_force_value :: Property+prop_lazy_mapMaybeWithKey_does_not_force_value = property $ do+ m <- forAll neMapGen+ assertNotForced $ NEML.mapMaybeWithKey (\_ _ -> Just (error "forced lazy NEMap value")) m++prop_strict_mapMaybeWithKey_forces_value :: Property+prop_strict_mapMaybeWithKey_forces_value = property $ do+ m <- forAll neMapGen+ assertForced $ NEMS.mapMaybeWithKey (\_ _ -> Just (error "forced strict NEMap value")) m++prop_lazy_mapAccumWithKey_does_not_force_value :: Property+prop_lazy_mapAccumWithKey_does_not_force_value = property $ do+ m <- forAll neMapGen+ assertNotForced $+ snd (NEML.mapAccumWithKey (\acc _ _ -> (acc, error "forced lazy NEMap value" :: Text)) () m)++prop_strict_mapAccumWithKey_forces_value :: Property+prop_strict_mapAccumWithKey_forces_value = property $ do+ m <- forAll neMapGen+ assertForced $+ snd (NEMS.mapAccumWithKey (\acc _ _ -> (acc, error "forced strict NEMap value" :: Text)) () m)++prop_lazy_fromListWith_does_not_force_value :: Property+prop_lazy_fromListWith_does_not_force_value = property $ do+ k <- forAll keyGen+ assertNotForced $+ NEML.fromListWith (\_ _ -> error "forced lazy NEMap value") ((k, T.empty) :| [(k, T.empty)])++prop_strict_fromListWith_forces_value :: Property+prop_strict_fromListWith_forces_value = property $ do+ k <- forAll keyGen+ assertForced $+ NEMS.fromListWith (\_ _ -> error "forced strict NEMap value") ((k, T.empty) :| [(k, T.empty)])++prop_lazy_insertMapWith_does_not_force_value :: Property+prop_lazy_insertMapWith_does_not_force_value = property $ do+ k <- forAll keyGen+ assertNotForced $+ NEML.insertMapWith (\_ _ -> error "forced lazy NEMap value") k T.empty (M.singleton k T.empty)++prop_strict_insertMapWith_forces_value :: Property+prop_strict_insertMapWith_forces_value = property $ do+ k <- forAll keyGen+ assertForced $+ NEMS.insertMapWith (\_ _ -> error "forced strict NEMap value") k T.empty (M.singleton k T.empty)++prop_lazy_updateWithKey_does_not_force_value :: Property+prop_lazy_updateWithKey_does_not_force_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertNotForced $ NEML.updateWithKey (\_ _ -> Just (error "forced lazy NEMap value")) k m++prop_strict_updateWithKey_forces_value :: Property+prop_strict_updateWithKey_forces_value = property $ do+ m <- forAll neMapGen+ k <- forAll (existingKeyOf m)+ assertForced $ NEMS.updateWithKey (\_ _ -> Just (error "forced strict NEMap value")) k m++-- | Two-key map with both keys deliberately mapped to the same target key,+-- so the combining function is guaranteed to run.+collidingMapKeysFixture :: MonadGen m => m (KeyType, NEMS.NEMap KeyType Text)+collidingMapKeysFixture = do+ k <- keyGen+ pure (k, NEML.fromList ((k, T.empty) :| [(overKX (+ 1) k, T.empty)]))++prop_lazy_mapKeysWith_does_not_force_value :: Property+prop_lazy_mapKeysWith_does_not_force_value = property $ do+ (k, m) <- forAll collidingMapKeysFixture+ assertNotForced $ NEML.mapKeysWith (\_ _ -> error "forced lazy NEMap value") (const k) m++prop_strict_mapKeysWith_forces_value :: Property+prop_strict_mapKeysWith_forces_value = property $ do+ (k, m) <- forAll collidingMapKeysFixture+ assertForced $ NEMS.mapKeysWith (\_ _ -> error "forced strict NEMap value") (const k) m++prop_lazy_traverseWithKey_does_not_force_value :: Property+prop_lazy_traverseWithKey_does_not_force_value = property $ do+ m <- forAll neMapGen+ assertNotForced $+ runIdentity (NEML.traverseWithKey (\_ _ -> Identity (error "forced lazy NEMap value" :: Text)) m)++prop_strict_traverseWithKey_forces_value :: Property+prop_strict_traverseWithKey_forces_value = property $ do+ m <- forAll neMapGen+ assertForced $+ runIdentity (NEMS.traverseWithKey (\_ _ -> Identity (error "forced strict NEMap value" :: Text)) m)++prop_lazy_traverseWithKey1_does_not_force_value :: Property+prop_lazy_traverseWithKey1_does_not_force_value = property $ do+ m <- forAll neMapGen+ assertNotForced $+ runIdentity (NEML.traverseWithKey1 (\_ _ -> Identity (error "forced lazy NEMap value" :: Text)) m)++prop_strict_traverseWithKey1_forces_value :: Property+prop_strict_traverseWithKey1_forces_value = property $ do+ m <- forAll neMapGen+ assertForced $+ runIdentity (NEMS.traverseWithKey1 (\_ _ -> Identity (error "forced strict NEMap value" :: Text)) m)++prop_lazy_traverseMaybeWithKey1_does_not_force_value :: Property+prop_lazy_traverseMaybeWithKey1_does_not_force_value = property $ do+ m <- forAll neMapGen+ assertNotForced $+ runIdentity+ (NEML.traverseMaybeWithKey1 (\_ _ -> Identity (Just (error "forced lazy NEMap value" :: Text))) m)++prop_strict_traverseMaybeWithKey1_forces_value :: Property+prop_strict_traverseMaybeWithKey1_forces_value = property $ do+ m <- forAll neMapGen+ assertForced $+ runIdentity+ (NEMS.traverseMaybeWithKey1 (\_ _ -> Identity (Just (error "forced strict NEMap value" :: Text))) m)++prop_valid_toMap :: Property+prop_valid_toMap =+ property $+ assert . M.valid . NEM.toMap =<< forAll neMapGen++prop_valid_insertMinMap :: Property+prop_valid_insertMinMap = property $ do+ n <- forAll $ do+ m <- mapGen+ let k = maybe dummyKey (subtract 1 . fst) $ M.lookupMin m+ v <- valGen+ pure $ NEM.insertMinMap k v m+ assert $ M.valid n++prop_valid_insertMaxMap :: Property+prop_valid_insertMaxMap = property $ do+ n <- forAll $ do+ m <- mapGen+ let k = maybe dummyKey ((+ 1) . fst) $ M.lookupMax m+ v <- valGen+ pure $ NEM.insertMaxMap k v m+ assert $ M.valid n++prop_valid_insertMapMin :: Property+prop_valid_insertMapMin = property $ do+ n <- forAll $ do+ m <- mapGen+ let k = maybe dummyKey (subtract 1 . fst) $ M.lookupMin m+ v <- valGen+ pure $ NEM.insertMapMin k v m+ assert $ NEM.valid n++prop_valid_insertMapMax :: Property+prop_valid_insertMapMax = property $ do+ n <- forAll $ do+ m <- mapGen+ let k = maybe dummyKey ((+ 1) . fst) $ M.lookupMax m+ v <- valGen+ pure $ NEM.insertMapMax k v m+ assert $ NEM.valid n++prop_toMapIso1 :: Property+prop_toMapIso1 = property $ do+ m0 <- forAll mapGen+ tripping+ m0+ NEM.nonEmptyMap+ (Identity . maybe M.empty NEM.toMap)++prop_toMapIso2 :: Property+prop_toMapIso2 = property $ do+ m0 <- forAll $ Gen.maybe neMapGen+ tripping+ m0+ (maybe M.empty NEM.toMap)+ (Identity . NEM.nonEmptyMap)++prop_read_show :: Property+prop_read_show = readShow neMapGen++prop_read1_show1 :: Property+prop_read1_show1 = readShow1 neMapGen++prop_show_show1 :: Property+prop_show_show1 = showShow1 neMapGen++prop_show_show2 :: Property+prop_show_show2 = showShow2 neMapGen++prop_splitRoot :: Property+prop_splitRoot = property $ do+ n <- forAll neMapGen+ let rs = NEM.splitRoot n+ allItems = foldMap1 NEM.keys rs+ n' = NEM.unions rs+ assert $ ascending allItems+ mapM_ (assert . (`NEM.isSubmapOf` n)) rs+ length allItems === length n'+ n === n'+ where+ ascending (x :| xs) = case NE.nonEmpty xs of+ Nothing -> True+ Just ys@(y :| _) -> x < y && ascending ys++prop_functorWithIndex :: Property+prop_functorWithIndex =+ property $ do+ m <- forAll neMapGen+ let f k v = v <> T.pack (show (getKX k))+ IFunctor.imap f m === NEM.mapWithKey f m++prop_foldableWithIndex :: Property+prop_foldableWithIndex =+ property $ do+ m <- forAll neMapGen+ IFoldable.ifoldMap (\k v -> [(k, v)]) m === toList (NEM.toList m)++prop_traversableWithIndex :: Property+prop_traversableWithIndex =+ property $ do+ m <- forAll neMapGen+ let f k v = v <> T.pack (show (getKX k))+ TWI.itraverse (\k v -> Identity (f k v)) m === Identity (NEM.mapWithKey f m)+ TWI.itraverse (\k v -> Const [(k, v)]) m === Const (toList (NEM.toList m))++prop_extract_duplicate :: Property+prop_extract_duplicate = property $ do+ n <- forAll neMapGen+ tripping+ n+ duplicate+ (Identity . extract)++prop_fmap_extract_duplicate :: Property+prop_fmap_extract_duplicate = property $ do+ n <- forAll neMapGen+ tripping+ n+ duplicate+ (Identity . fmap extract)++prop_duplicate_duplicate :: Property+prop_duplicate_duplicate = property $ do+ n <- forAll neMapGen+ let dd1 = duplicate . duplicate $ n+ dd2 = fmap duplicate . duplicate $ n+ assert $ NEM.valid dd1+ assert $ NEM.valid dd2+ dd1 === dd2++prop_insertMapWithKey :: Property+prop_insertMapWithKey =+ ttProp+ (gf3 valGen :?> GTKey :-> GTVal :-> GTMap :-> TTNEMap)+ M.insertWithKey+ NEM.insertMapWithKey++prop_singleton :: Property+prop_singleton =+ ttProp+ (GTKey :-> GTVal :-> TTNEMap)+ M.singleton+ NEM.singleton++prop_fromSet :: Property+prop_fromSet =+ ttProp+ (gf1 valGen :?> GTNESet :-> TTNEMap)+ M.fromSet+ NEM.fromSet++prop_fromAscList :: Property+prop_fromAscList =+ ttProp+ (GTSorted STAsc (GTNEList Nothing (GTKey :&: GTVal)) :-> TTNEMap)+ M.fromAscList+ NEM.fromAscList++prop_fromDescList :: Property+prop_fromDescList =+ ttProp+ (GTSorted STDesc (GTNEList Nothing (GTKey :&: GTVal)) :-> TTNEMap)+ M.fromDescList+ NEM.fromDescList++prop_fromAscListWithKey :: Property+prop_fromAscListWithKey =+ ttProp+ (gf3 valGen :?> GTSorted STAsc (GTNEList Nothing (GTKey :&: GTVal)) :-> TTNEMap)+ M.fromAscListWithKey+ NEM.fromAscListWithKey++prop_fromDescListWithKey :: Property+prop_fromDescListWithKey =+ ttProp+ (gf3 valGen :?> GTSorted STDesc (GTNEList Nothing (GTKey :&: GTVal)) :-> TTNEMap)+ M.fromDescListWithKey+ NEM.fromDescListWithKey++prop_fromDistinctAscList :: Property+prop_fromDistinctAscList =+ ttProp+ (GTSorted STDistinctAsc (GTNEList Nothing (GTKey :&: GTVal)) :-> TTNEMap)+ M.fromDistinctAscList+ NEM.fromDistinctAscList++prop_fromDistinctDescList :: Property+prop_fromDistinctDescList =+ ttProp+ (GTSorted STDistinctDesc (GTNEList Nothing (GTKey :&: GTVal)) :-> TTNEMap)+ M.fromDistinctDescList+ NEM.fromDistinctDescList++prop_fromListWithKey :: Property+prop_fromListWithKey =+ ttProp+ (gf3 valGen :?> GTNEList Nothing (GTKey :&: GTVal) :-> TTNEMap)+ M.fromListWithKey+ NEM.fromListWithKey++prop_toFromOverloadedList :: Property+prop_toFromOverloadedList =+ property $ do+ s <- forAll neMapGen+ s === Exts.fromList (Exts.toList s)++prop_fromToOverloadedList :: Property+prop_fromToOverloadedList =+ property $ do+ l <- forAll neKeyListUniqGen+ l === Exts.toList (Exts.fromList @(NEM.NEMap KeyType Text) l)++prop_insert :: Property+prop_insert =+ ttProp+ (GTKey :-> GTVal :-> GTNEMap :-> TTNEMap)+ M.insert+ NEM.insert++prop_insertWithKey :: Property+prop_insertWithKey =+ ttProp+ (gf3 valGen :?> GTKey :-> GTVal :-> GTNEMap :-> TTNEMap)+ M.insertWithKey+ NEM.insertWithKey++prop_delete :: Property+prop_delete =+ ttProp+ (GTKey :-> GTNEMap :-> TTMap)+ M.delete+ NEM.delete++prop_deleteMaybe :: Property+prop_deleteMaybe =+ property $ do+ k <- forAll keyGen+ m <- forAll neMapGen+ NEM.deleteMaybe k m === NEM.nonEmptyMap (M.delete k (NEM.toMap m))++prop_adjustWithKey :: Property+prop_adjustWithKey =+ ttProp+ (gf2 valGen :?> GTKey :-> GTNEMap :-> TTNEMap)+ M.adjustWithKey+ NEM.adjustWithKey++prop_updateWithKey :: Property+prop_updateWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTKey :-> GTNEMap :-> TTMap)+ M.updateWithKey+ NEM.updateWithKey++prop_updateLookupWithKey :: Property+prop_updateLookupWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTKey :-> GTNEMap :-> TTMaybe TTVal :*: TTMap)+ M.updateLookupWithKey+ NEM.updateLookupWithKey++prop_alter :: Property+prop_alter =+ ttProp+ (gf1 (Gen.maybe valGen) :?> GTKey :-> GTNEMap :-> TTMap)+ M.alter+ NEM.alter++prop_alter' :: Property+prop_alter' =+ ttProp+ (gf1 valGen :?> GTKey :-> GTNEMap :-> TTNEMap)+ (M.alter . fmap Just)+ NEM.alter'++prop_alterF :: Property+prop_alterF =+ ttProp+ ( gf1 (Gen.maybe valGen)+ :?> GTKey+ :-> GTNEMap+ :-> TTCtx (GTMaybe GTVal :-> TTMap) (TTMaybe TTVal)+ )+ (M.alterF . Context)+ (NEM.alterF . Context)++prop_alterF_rules_Const :: Property+prop_alterF_rules_Const =+ ttProp+ ( gf1 (Const <$> valGen)+ :?> GTKey+ :-> GTNEMap+ :-> TTOther+ )+ (\f k m -> getConst (M.alterF f k m))+ (\f k m -> getConst (NEM.alterF f k m))++prop_alterF_rules_Identity :: Property+prop_alterF_rules_Identity =+ ttProp+ ( gf1 (Identity <$> Gen.maybe valGen)+ :?> GTKey+ :-> GTNEMap+ :-> TTMap+ )+ (\f k m -> runIdentity (M.alterF f k m))+ (\f k m -> runIdentity (NEM.alterF f k m))++prop_alterF' :: Property+prop_alterF' =+ ttProp+ (gf1 valGen :?> GTKey :-> GTNEMap :-> TTCtx (GTVal :-> TTNEMap) (TTMaybe TTVal))+ (M.alterF . Context . fmap Just)+ (NEM.alterF' . Context)++prop_alterF'_rules_Const :: Property+prop_alterF'_rules_Const =+ ttProp+ ( gf1 (Const <$> valGen)+ :?> GTKey+ :-> GTNEMap+ :-> TTOther+ )+ (\f k m -> let f' = fmap Just . f in getConst (M.alterF f' k m))+ (\f k m -> getConst (NEM.alterF' f k m))++-- -- | This fails, but isn't possible to fix without copying-and-pasting more+-- -- in code from containers.+-- prop_alterF'_rules_Identity :: Property+-- prop_alterF'_rules_Identity = ttProp ( gf1 (Identity <$> valGen)+-- :?> GTKey+-- :-> GTNEMap+-- :-> TTNEMap+-- )+-- (\f k m -> let f' = fmap Just . f in runIdentity (M.alterF f' k m))+-- (\f k m -> runIdentity (NEM.alterF' f k m))++prop_lookup :: Property+prop_lookup =+ ttProp+ (GTKey :-> GTNEMap :-> TTMaybe TTVal)+ M.lookup+ NEM.lookup++prop_findWithDefault :: Property+prop_findWithDefault =+ ttProp+ (GTVal :-> GTKey :-> GTNEMap :-> TTVal)+ M.findWithDefault+ NEM.findWithDefault++prop_member :: Property+prop_member =+ ttProp+ (GTKey :-> GTNEMap :-> TTOther)+ M.member+ NEM.member++prop_notMember :: Property+prop_notMember =+ ttProp+ (GTKey :-> GTNEMap :-> TTOther)+ M.notMember+ NEM.notMember++prop_lookupLT :: Property+prop_lookupLT =+ ttProp+ (GTKey :-> GTNEMap :-> TTMaybe (TTKey :*: TTVal))+ M.lookupLT+ NEM.lookupLT++prop_lookupGT :: Property+prop_lookupGT =+ ttProp+ (GTKey :-> GTNEMap :-> TTMaybe (TTKey :*: TTVal))+ M.lookupGT+ NEM.lookupGT++prop_lookupLE :: Property+prop_lookupLE =+ ttProp+ (GTKey :-> GTNEMap :-> TTMaybe (TTKey :*: TTVal))+ M.lookupLE+ NEM.lookupLE++prop_lookupGE :: Property+prop_lookupGE =+ ttProp+ (GTKey :-> GTNEMap :-> TTMaybe (TTKey :*: TTVal))+ M.lookupGE+ NEM.lookupGE++prop_size :: Property+prop_size =+ ttProp+ (GTNEMap :-> TTOther)+ M.size+ NEM.size++prop_union :: Property+prop_union =+ ttProp+ (GTNEMap :-> GTNEMap :-> TTNEMap)+ M.union+ NEM.union++prop_unionMapLeft :: Property+prop_unionMapLeft =+ ttProp+ (GTMap :-> GTNEMap :-> TTNEMap)+ M.union+ NEM.unionMapLeft++prop_unionMapRight :: Property+prop_unionMapRight =+ ttProp+ (GTNEMap :-> GTMap :-> TTNEMap)+ M.union+ NEM.unionMapRight++prop_unionWith :: Property+prop_unionWith =+ ttProp+ (gf2 valGen :?> GTNEMap :-> GTNEMap :-> TTNEMap)+ M.unionWith+ NEM.unionWith++prop_unionMapWithLeft :: Property+prop_unionMapWithLeft =+ ttProp+ (gf2 valGen :?> GTMap :-> GTNEMap :-> TTNEMap)+ M.unionWith+ NEM.unionMapWithLeft++prop_unionMapWithRight :: Property+prop_unionMapWithRight =+ ttProp+ (gf2 valGen :?> GTNEMap :-> GTMap :-> TTNEMap)+ M.unionWith+ NEM.unionMapWithRight++prop_unionWithKey :: Property+prop_unionWithKey =+ ttProp+ (gf3 valGen :?> GTNEMap :-> GTNEMap :-> TTNEMap)+ M.unionWithKey+ NEM.unionWithKey++prop_unionMapWithKeyLeft :: Property+prop_unionMapWithKeyLeft =+ ttProp+ (gf3 valGen :?> GTMap :-> GTNEMap :-> TTNEMap)+ M.unionWithKey+ NEM.unionMapWithKeyLeft++prop_unionMapWithKeyRight :: Property+prop_unionMapWithKeyRight =+ ttProp+ (gf3 valGen :?> GTNEMap :-> GTMap :-> TTNEMap)+ M.unionWithKey+ NEM.unionMapWithKeyRight++prop_unions :: Property+prop_unions =+ ttProp+ (GTNEList (Just (Range.linear 2 5)) GTNEMap :-> TTNEMap)+ M.unions+ NEM.unions++prop_unionsWith :: Property+prop_unionsWith =+ ttProp+ (gf2 valGen :?> GTNEList (Just (Range.linear 2 5)) GTNEMap :-> TTNEMap)+ M.unionsWith+ NEM.unionsWith++prop_difference :: Property+prop_difference =+ ttProp+ (GTNEMap :-> GTNEMap :-> TTMap)+ M.difference+ NEM.difference++prop_differenceWithKey :: Property+prop_differenceWithKey =+ ttProp+ (gf3 (Gen.maybe valGen) :?> GTNEMap :-> GTNEMap :-> TTMap)+ M.differenceWithKey+ NEM.differenceWithKey++prop_intersection :: Property+prop_intersection =+ ttProp+ (GTNEMap :-> GTNEMap :-> TTMap)+ M.intersection+ NEM.intersection++prop_intersectionWithKey :: Property+prop_intersectionWithKey =+ ttProp+ (gf3 valGen :?> GTNEMap :-> GTNEMap :-> TTMap)+ M.intersectionWithKey+ NEM.intersectionWithKey++prop_map :: Property+prop_map =+ ttProp+ (gf1 valGen :?> GTNEMap :-> TTNEMap)+ M.map+ NEM.map++prop_map_rules_map :: Property+prop_map_rules_map =+ ttProp+ (gf1 valGen :?> gf1 valGen :?> GTNEMap :-> TTNEMap)+ (\f g xs -> M.map f (M.map g xs))+ (\f g xs -> NEM.map f (NEM.map g xs))++prop_map_rules_coerce :: Property+prop_map_rules_coerce =+ ttProp+ (GTNEMap :-> TTNEMap)+ (M.map @Text @Text coerce)+ (NEM.map @Text @Text coerce)++prop_map_rules_mapWithKey :: Property+prop_map_rules_mapWithKey =+ ttProp+ (gf1 valGen :?> gf2 valGen :?> GTNEMap :-> TTNEMap)+ (\f g xs -> M.map f (M.mapWithKey g xs))+ (\f g xs -> NEM.map f (NEM.mapWithKey g xs))++prop_mapWithKey :: Property+prop_mapWithKey =+ ttProp+ (gf2 valGen :?> GTNEMap :-> TTNEMap)+ M.mapWithKey+ NEM.mapWithKey++prop_mapWithKey_rules_mapWithKey :: Property+prop_mapWithKey_rules_mapWithKey =+ ttProp+ (gf2 valGen :?> gf2 valGen :?> GTNEMap :-> TTNEMap)+ (\f g xs -> M.mapWithKey f (M.mapWithKey g xs))+ (\f g xs -> NEM.mapWithKey f (NEM.mapWithKey g xs))++prop_mapWithKey_rules_map :: Property+prop_mapWithKey_rules_map =+ ttProp+ (gf2 valGen :?> gf1 valGen :?> GTNEMap :-> TTNEMap)+ (\f g xs -> M.mapWithKey f (M.map g xs))+ (\f g xs -> NEM.mapWithKey f (NEM.map g xs))++prop_traverseWithKey1 :: Property+prop_traverseWithKey1 =+ ttProp+ (gf2 valGen :?> GTNEMap :-> TTBazaar GTVal TTNEMap TTVal)+ (\f -> M.traverseWithKey (\k -> (`More` Done (f k))))+ (\f -> NEM.traverseWithKey1 (\k -> (`More` Done (f k))))++prop_traverseWithKey :: Property+prop_traverseWithKey =+ ttProp+ (gf2 valGen :?> GTNEMap :-> TTBazaar GTVal TTNEMap TTVal)+ (\f -> M.traverseWithKey (\k -> (`More` Done (f k))))+ (\f -> NEM.traverseWithKey (\k -> (`More` Done (f k))))++prop_traverseMaybeWithKey1 :: Property+prop_traverseMaybeWithKey1 =+ ttProp+ (gf2 valGen :?> GTNEMap :-> TTBazaar (GTMaybe GTVal) TTMap TTVal)+ (\f -> M.traverseMaybeWithKey (\k -> (`More` Done (fmap (f k)))))+ (\f -> NEM.traverseMaybeWithKey1 (\k -> (`More` Done (fmap (f k)))))++prop_traverseMaybeWithKey :: Property+prop_traverseMaybeWithKey =+ ttProp+ (gf2 valGen :?> GTNEMap :-> TTBazaar (GTMaybe GTVal) TTMap TTVal)+ (\f -> M.traverseMaybeWithKey (\k -> (`More` Done (fmap (f k)))))+ (\f -> NEM.traverseMaybeWithKey (\k -> (`More` Done (fmap (f k)))))++prop_sequence1 :: Property+prop_sequence1 =+ ttProp+ (GTNEMap :-> TTBazaar GTVal TTNEMap TTVal)+ (sequenceA . fmap (`More` Done id))+ (sequence1 . fmap (`More` Done id))+{-# ANN prop_sequence1 "HLint: ignore Use traverse" #-}++prop_sequenceA :: Property+prop_sequenceA =+ ttProp+ (GTNEMap :-> TTBazaar GTVal TTNEMap TTVal)+ (sequenceA . fmap (`More` Done id))+ (sequenceA . fmap (`More` Done id))+{-# ANN prop_sequenceA "HLint: ignore Use traverse" #-}++prop_mapAccumWithKey :: Property+prop_mapAccumWithKey =+ ttProp+ ( gf3 ((,) <$> valGen <*> valGen)+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ :*: TTNEMap+ )+ M.mapAccumWithKey+ NEM.mapAccumWithKey++prop_mapAccumRWithKey :: Property+prop_mapAccumRWithKey =+ ttProp+ ( gf3 ((,) <$> valGen <*> valGen)+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ :*: TTNEMap+ )+ M.mapAccumRWithKey+ NEM.mapAccumRWithKey++prop_mapKeys :: Property+prop_mapKeys =+ ttProp+ (gf1 keyGen :?> GTNEMap :-> TTNEMap)+ M.mapKeys+ NEM.mapKeys++prop_mapKeysWith :: Property+prop_mapKeysWith =+ ttProp+ ( gf2 valGen+ :?> gf1 keyGen+ :?> GTNEMap+ :-> TTNEMap+ )+ M.mapKeysWith+ NEM.mapKeysWith++prop_mapKeysMonotonic :: Property+prop_mapKeysMonotonic =+ ttProp+ (GF valGen go :?> GTNEMap :-> TTNEMap)+ M.mapKeysMonotonic+ NEM.mapKeysMonotonic+ where+ go f (K i t) = K (i * 2) (f t)++prop_foldr :: Property+prop_foldr =+ ttProp+ ( gf2 valGen+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ )+ M.foldr+ NEM.foldr++prop_foldl :: Property+prop_foldl =+ ttProp+ ( gf2 valGen+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ )+ M.foldl+ NEM.foldl++prop_foldr1 :: Property+prop_foldr1 =+ ttProp+ ( gf2 valGen+ :?> GTNEMap+ :-> TTOther+ )+ foldr1+ NEM.foldr1++prop_foldl1 :: Property+prop_foldl1 =+ ttProp+ ( gf2 valGen+ :?> GTNEMap+ :-> TTOther+ )+ foldl1+ NEM.foldl1++prop_foldrWithKey :: Property+prop_foldrWithKey =+ ttProp+ ( gf3 valGen+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ )+ M.foldrWithKey+ NEM.foldrWithKey++prop_foldlWithKey :: Property+prop_foldlWithKey =+ ttProp+ ( gf3 valGen+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ )+ M.foldlWithKey+ NEM.foldlWithKey++prop_foldMapWithKey :: Property+prop_foldMapWithKey =+ ttProp+ (gf2 valGen :?> GTNEMap :-> TTOther)+ M.foldMapWithKey+ NEM.foldMapWithKey++prop_foldr' :: Property+prop_foldr' =+ ttProp+ ( gf2 valGen+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ )+ M.foldr'+ NEM.foldr'++prop_foldl' :: Property+prop_foldl' =+ ttProp+ ( gf2 valGen+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ )+ M.foldl'+ NEM.foldl'++prop_foldr1' :: Property+prop_foldr1' =+ ttProp+ ( gf2 valGen+ :?> GTNEMap+ :-> TTOther+ )+ foldr1+ NEM.foldr1'++prop_foldl1' :: Property+prop_foldl1' =+ ttProp+ ( gf2 valGen+ :?> GTNEMap+ :-> TTOther+ )+ foldl1+ NEM.foldl1'++prop_foldrWithKey' :: Property+prop_foldrWithKey' =+ ttProp+ ( gf3 valGen+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ )+ M.foldrWithKey'+ NEM.foldrWithKey'++prop_foldlWithKey' :: Property+prop_foldlWithKey' =+ ttProp+ ( gf3 valGen+ :?> GTOther valGen+ :-> GTNEMap+ :-> TTOther+ )+ M.foldlWithKey'+ NEM.foldlWithKey'++prop_elems :: Property+prop_elems =+ ttProp+ (GTNEMap :-> TTNEList TTVal)+ M.elems+ NEM.elems++prop_keys :: Property+prop_keys =+ ttProp+ (GTNEMap :-> TTNEList TTKey)+ M.keys+ NEM.keys++prop_assocs :: Property+prop_assocs =+ ttProp+ (GTNEMap :-> TTNEList (TTKey :*: TTVal))+ M.assocs+ NEM.assocs++prop_keysSet :: Property+prop_keysSet =+ ttProp+ (GTNEMap :-> TTNESet)+ M.keysSet+ NEM.keysSet++prop_toList :: Property+prop_toList =+ ttProp+ (GTNEMap :-> TTNEList (TTKey :*: TTVal))+ M.toList+ NEM.toList++prop_toDescList :: Property+prop_toDescList =+ ttProp+ (GTNEMap :-> TTNEList (TTKey :*: TTVal))+ M.toDescList+ NEM.toDescList++prop_filter :: Property+prop_filter =+ ttProp+ (gf1 Gen.bool :?> GTNEMap :-> TTMap)+ M.filter+ NEM.filter++prop_filterWithKey :: Property+prop_filterWithKey =+ ttProp+ (gf2 Gen.bool :?> GTNEMap :-> TTMap)+ M.filterWithKey+ NEM.filterWithKey++prop_restrictKeys :: Property+prop_restrictKeys =+ ttProp+ (GTNEMap :-> GTSet :-> TTMap)+ M.restrictKeys+ NEM.restrictKeys++prop_withoutKeys :: Property+prop_withoutKeys =+ ttProp+ (GTNEMap :-> GTSet :-> TTMap)+ M.withoutKeys+ NEM.withoutKeys++prop_partitionWithKey :: Property+prop_partitionWithKey =+ ttProp+ (gf2 Gen.bool :?> GTNEMap :-> TTThese TTNEMap TTNEMap)+ M.partitionWithKey+ NEM.partitionWithKey++prop_takeWhileAntitone :: Property+prop_takeWhileAntitone =+ ttProp+ (GTNEMap :-> TTMap)+ (M.takeWhileAntitone ((< 0) . getKX))+ (NEM.takeWhileAntitone ((< 0) . getKX))++prop_dropWhileAntitone :: Property+prop_dropWhileAntitone =+ ttProp+ (GTNEMap :-> TTMap)+ (M.dropWhileAntitone ((< 0) . getKX))+ (NEM.dropWhileAntitone ((< 0) . getKX))++prop_spanAntitone :: Property+prop_spanAntitone =+ ttProp+ (GTNEMap :-> TTThese TTNEMap TTNEMap)+ (M.spanAntitone ((< 0) . getKX))+ (NEM.spanAntitone ((< 0) . getKX))++prop_mapMaybeWithKey :: Property+prop_mapMaybeWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTNEMap :-> TTMap)+ M.mapMaybeWithKey+ NEM.mapMaybeWithKey++prop_mapEitherWithKey :: Property+prop_mapEitherWithKey =+ ttProp+ ( gf2 (Gen.choice [Left <$> valGen, Right <$> valGen])+ :?> GTNEMap+ :-> TTThese TTNEMap TTNEMap+ )+ M.mapEitherWithKey+ NEM.mapEitherWithKey++prop_split :: Property+prop_split =+ ttProp+ (GTKey :-> GTNEMap :-> TTMThese TTNEMap TTNEMap)+ M.split+ NEM.split++prop_splitLookup :: Property+prop_splitLookup =+ ttProp+ (GTKey :-> GTNEMap :-> TTTThese TTVal TTNEMap TTNEMap)+ (\k -> (\(x, y, z) -> (y, x, z)) . M.splitLookup k)+ NEM.splitLookup++prop_isSubmapOfBy :: Property+prop_isSubmapOfBy =+ ttProp+ (gf2 Gen.bool :?> GTNEMap :-> GTNEMap :-> TTOther)+ M.isSubmapOfBy+ NEM.isSubmapOfBy++prop_isProperSubmapOfBy :: Property+prop_isProperSubmapOfBy =+ ttProp+ (gf2 Gen.bool :?> GTNEMap :-> GTNEMap :-> TTOther)+ M.isProperSubmapOfBy+ NEM.isProperSubmapOfBy++prop_lookupIndex :: Property+prop_lookupIndex =+ ttProp+ (GTKey :-> GTNEMap :-> TTMaybe TTOther)+ M.lookupIndex+ NEM.lookupIndex++prop_elemAt :: Property+prop_elemAt =+ ttProp+ (GTSize :-> GTNEMap :-> TTKey :*: TTVal)+ (\i m -> M.elemAt (i `mod` M.size m) m)+ (\i m -> NEM.elemAt (i `mod` NEM.size m) m)++prop_adjustAt :: Property+prop_adjustAt =+ ttProp+ (gf2 valGen :?> GTSize :-> GTNEMap :-> TTNEMap)+ (\f i m -> M.updateAt (\k -> Just . f k) (i `mod` M.size m) m)+ (\f i m -> NEM.adjustAt f (i `mod` NEM.size m) m)++prop_updateAt :: Property+prop_updateAt =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTSize :-> GTNEMap :-> TTMap)+ (\f i m -> M.updateAt f (i `mod` M.size m) m)+ (\f i m -> NEM.updateAt f (i `mod` NEM.size m) m)++prop_deleteAt :: Property+prop_deleteAt =+ ttProp+ (GTSize :-> GTNEMap :-> TTMap)+ (\i m -> M.deleteAt (i `mod` M.size m) m)+ (\i m -> NEM.deleteAt (i `mod` NEM.size m) m)++prop_take :: Property+prop_take =+ ttProp+ (GTSize :-> GTNEMap :-> TTMap)+ M.take+ NEM.take++prop_drop :: Property+prop_drop =+ ttProp+ (GTSize :-> GTNEMap :-> TTMap)+ M.drop+ NEM.drop++prop_splitAt :: Property+prop_splitAt =+ ttProp+ (GTSize :-> GTNEMap :-> TTThese TTNEMap TTNEMap)+ M.splitAt+ NEM.splitAt++prop_findMin :: Property+prop_findMin =+ ttProp+ (GTNEMap :-> TTKey :*: TTVal)+ M.findMin+ NEM.findMin++prop_findMax :: Property+prop_findMax =+ ttProp+ (GTNEMap :-> TTKey :*: TTVal)+ M.findMax+ NEM.findMax++prop_deleteMin :: Property+prop_deleteMin =+ ttProp+ (GTNEMap :-> TTMap)+ M.deleteMin+ NEM.deleteMin++prop_deleteMax :: Property+prop_deleteMax =+ ttProp+ (GTNEMap :-> TTMap)+ M.deleteMax+ NEM.deleteMax++prop_deleteFindMin :: Property+prop_deleteFindMin =+ ttProp+ (GTNEMap :-> (TTKey :*: TTVal) :*: TTMap)+ M.deleteFindMin+ NEM.deleteFindMin++prop_deleteFindMax :: Property+prop_deleteFindMax =+ ttProp+ (GTNEMap :-> (TTKey :*: TTVal) :*: TTMap)+ M.deleteFindMax+ NEM.deleteFindMax++prop_updateMinWithKey :: Property+prop_updateMinWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTNEMap :-> TTMap)+ M.updateMinWithKey+ NEM.updateMinWithKey++prop_updateMaxWithKey :: Property+prop_updateMaxWithKey =+ ttProp+ (gf2 (Gen.maybe valGen) :?> GTNEMap :-> TTMap)+ M.updateMaxWithKey+ NEM.updateMaxWithKey++prop_adjustMinWithKey :: Property+prop_adjustMinWithKey =+ ttProp+ (gf2 valGen :?> GTNEMap :-> TTNEMap)+ (M.updateMinWithKey . (fmap . fmap) Just)+ NEM.adjustMinWithKey++prop_adjustMaxWithKey :: Property+prop_adjustMaxWithKey =+ ttProp+ (gf2 valGen :?> GTNEMap :-> TTNEMap)+ (M.updateMaxWithKey . (fmap . fmap) Just)+ NEM.adjustMaxWithKey++prop_minView :: Property+prop_minView =+ ttProp+ (GTNEMap :-> TTMaybe (TTVal :*: TTMap))+ M.minView+ (Just . NEM.minView)++prop_maxView :: Property+prop_maxView =+ ttProp+ (GTNEMap :-> TTMaybe (TTVal :*: TTMap))+ M.maxView+ (Just . NEM.maxView)++prop_elem :: Property+prop_elem =+ ttProp+ (GTVal :-> GTNEMap :-> TTOther)+ elem+ elem++prop_fold1 :: Property+prop_fold1 =+ ttProp+ (GTNEMap :-> TTVal)+ fold+ fold1++prop_fold :: Property+prop_fold =+ ttProp+ (GTNEMap :-> TTVal)+ fold+ fold++prop_foldMap1 :: Property+prop_foldMap1 =+ ttProp+ (gf1 valGen :?> GTNEMap :-> TTOther)+ (\f -> foldMap ((: []) . f))+ (\f -> foldMap1 ((: []) . f))++prop_foldMap :: Property+prop_foldMap =+ ttProp+ (gf1 valGen :?> GTNEMap :-> TTOther)+ (\f -> foldMap ((: []) . f))+ (\f -> foldMap ((: []) . f))++prop_alt :: Property+prop_alt =+ ttProp+ (GTNEMap :-> GTNEMap :-> TTNEMap)+ (<!>)+ (<!>)
test/Tests/Util.hs view
@@ -27,6 +27,8 @@ TestType (..), ttProp, groupTree,+ assertForced,+ assertNotForced, readShow, readShow1, showShow1,@@ -55,9 +57,11 @@ ) where import Control.Applicative+import Control.Exception (ErrorCall, evaluate, try) import Control.Monad import Data.Bifunctor import Data.Char+import Data.Either (isLeft) import Data.Foldable import Data.Function import Data.Functor.Apply@@ -116,6 +120,22 @@ mkName = map deUnderscore . drop (length @[] @Char "prop_") deUnderscore '_' = ' ' deUnderscore c = c++-- | Assert that evaluating a value to WHNF throws (i.e. that constructing+-- it must have forced some 'error'-laden thunk buried inside). Used to+-- test the strict interfaces.+assertForced :: a -> PropertyT IO ()+assertForced x = do+ r <- evalIO $ try @ErrorCall (evaluate x)+ assert (isLeft r)++-- | Assert that evaluating a value to WHNF does /not/ throw, even when it+-- contains an 'error'-laden thunk that only a strict interface would have+-- forced. Used to test the lazy interfaces.+assertNotForced :: a -> PropertyT IO ()+assertNotForced x = do+ _ <- evalIO $ evaluate x+ success -- | test for stability data K a b = K {getKX :: !a, getKY :: !b}