non-empty-containers 0.1.1.0 → 0.1.2.0
raw patch · 3 files changed
+86/−8 lines, 3 filesdep +semigroupoids
Dependencies added: semigroupoids
Files
- non-empty-containers.cabal +2/−1
- src/Data/Map/NonEmpty.hs +49/−2
- src/Data/Set/NonEmpty.hs +35/−5
non-empty-containers.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: non-empty-containers-version: 0.1.1.0+version: 0.1.2.0 description: Please see the README on GitHub at <https://github.com/andrewthad/non-empty-containers#readme> homepage: https://github.com/andrewthad/non-empty-containers#readme bug-reports: https://github.com/andrewthad/non-empty-containers/issues@@ -24,6 +24,7 @@ build-depends: base >=4.11 && <5 , containers >= 0.5.10 && < 0.7+ , semigroupoids >= 5.2.0 && < 6.0 ghc-options: -O2 -Wall default-language: Haskell2010
src/Data/Map/NonEmpty.hs view
@@ -1,18 +1,27 @@+{-# LANGUAGE DeriveFunctor #-}+ module Data.Map.NonEmpty ( NonEmptyMap , singleton , lookup+ , foldl1'+ , foldr1'+ , ) where -import Prelude hiding (lookup)+import Prelude hiding (lookup,foldr1,foldr) import Data.Bool (bool)+import Data.Semigroup.Foldable (Foldable1)+import Data.List.NonEmpty (NonEmpty((:|))) +import qualified Data.Foldable as F import qualified Data.Map as M import qualified Data.Map.Strict as MS+import qualified Data.Semigroup.Foldable -- | A non-empty map. data NonEmptyMap k v = NonEmptyMap !k v !(M.Map k v)- deriving (Eq,Ord)+ deriving (Eq,Ord,Functor) -- | A map with a single element. singleton :: k -> v -> NonEmptyMap k v@@ -32,7 +41,45 @@ LT -> NonEmptyMap xk xv (MS.unionWith (<>) xs (M.insertWith (<>) yk yv ys)) GT -> NonEmptyMap yk yv (MS.unionWith (<>) (M.insertWith (<>) xk xv xs) ys) +foldr1 :: (v -> v -> v) -> NonEmptyMap k v -> v+foldr1 f (NonEmptyMap _ v m) = case M.maxView m of+ Nothing -> v+ Just (y,m') -> f v (M.foldr f y m')++foldMap1 :: Semigroup m => (v -> m) -> NonEmptyMap k v -> m+foldMap1 f (NonEmptyMap _ v m) = case M.maxView m of+ Nothing -> f v+ Just (x,m') -> f v <> M.foldr (\c d -> f c <> d) (f x) m'+ instance (Ord k, Semigroup v) => Semigroup (NonEmptyMap k v) where (<>) = unionAppend +instance Foldable (NonEmptyMap k) where+ fold (NonEmptyMap _ v m) = v <> F.fold m+ foldMap f (NonEmptyMap _ v m) = f v <> foldMap f m+ foldl f a (NonEmptyMap _ v m) = M.foldl f (f a v) m+ foldr f a (NonEmptyMap _ v m) = case M.maxView m of+ Nothing -> f v a+ Just (y,m') -> f v (M.foldr f (f y a) m')+ foldl1 f (NonEmptyMap _ v m) = M.foldl f v m+ foldr1 = foldr1+ length (NonEmptyMap _ _ m) = 1 + M.size m+ null _ = False+ minimum = foldl1' min+ maximum = foldl1' max +instance Foldable1 (NonEmptyMap k) where+ toNonEmpty = elems+ fold1 = foldr1 (<>)+ foldMap1 = foldMap1++elems :: NonEmptyMap k v -> NonEmpty v+elems (NonEmptyMap _ v m) = v :| M.elems m++foldl1' :: (v -> v -> v) -> NonEmptyMap k v -> v+foldl1' f (NonEmptyMap _ v m) = M.foldl' f v m++foldr1' :: (v -> v -> v) -> NonEmptyMap k v -> v+foldr1' f (NonEmptyMap _ v m) = case M.maxView m of+ Nothing -> v+ Just (y,m') -> let !k = M.foldr' f y m' in f v k
src/Data/Set/NonEmpty.hs view
@@ -3,13 +3,19 @@ , singleton , member , toSet+ , fromSet , toNonEmpty , fromNonEmpty ) where -import Data.Foldable+import Prelude hiding (foldr1,foldr)+ import Data.List.NonEmpty+import Data.Semigroup.Foldable (Foldable1)+ import qualified Data.Set as S+import qualified Data.Foldable as F+import qualified Data.Semigroup.Foldable -- | A non-empty set. data NonEmptySet a = NonEmptySet !a !(S.Set a)@@ -38,6 +44,10 @@ -- me to do an unsafe insert on the left-hand side of a set. toSet (NonEmptySet x xs) = S.insert x xs +-- | Attempt to create a non-empty set from a set.+fromSet :: Ord a => S.Set a -> Maybe (NonEmptySet a)+fromSet s = fmap (uncurry NonEmptySet) (S.minView s)+ -- | Create a non-empty set from a non-empty list. fromNonEmpty :: Ord a => NonEmpty a -> NonEmptySet a fromNonEmpty (x :| xs) = case S.minView s of@@ -49,22 +59,42 @@ where s = S.fromList xs +foldr :: (a -> b -> b) -> b -> NonEmptySet a -> b+foldr f b (NonEmptySet a m) = case S.maxView m of+ Nothing -> f a b+ Just (y,m') -> f a (S.foldr f (f y b) m')++foldr1 :: (a -> a -> a) -> NonEmptySet a -> a+foldr1 f (NonEmptySet a s) = case S.maxView s of+ Nothing -> a+ Just (m,s') -> f a (S.foldr f m s')++foldMap1 :: Semigroup m => (a -> m) -> NonEmptySet a -> m+foldMap1 f (NonEmptySet a s) = case S.maxView s of+ Nothing -> f a+ Just (m,s') -> f a <> S.foldr (\c d -> f c <> d) (f m) s'+ instance Show a => Show (NonEmptySet a) where showsPrec p xs = showParen (p > 10) $ showString "fromNonEmpty " . shows (toNonEmpty xs) instance Foldable NonEmptySet where- fold (NonEmptySet a s) = a <> fold s+ fold (NonEmptySet a s) = a <> F.fold s foldMap f (NonEmptySet a s) = f a <> foldMap f s foldl1 f (NonEmptySet a s) = S.foldl f a s- foldr1 f (NonEmptySet a s) = case S.maxView s of- Nothing -> a- Just (m,s') -> f a (S.foldr f m s')+ foldr1 = foldr1+ foldr = foldr minimum (NonEmptySet a _) = a maximum (NonEmptySet a s) = case S.lookupMax s of Nothing -> a Just m -> m length (NonEmptySet _ s) = 1 + S.size s+ null _ = False++instance Foldable1 NonEmptySet where+ toNonEmpty = toNonEmpty+ fold1 = foldr1 (<>)+ foldMap1 = foldMap1 instance Ord a => Semigroup (NonEmptySet a) where NonEmptySet x xs <> NonEmptySet y ys = case compare x y of