Unique 0.4.7.2 → 0.4.7.5
raw patch · 4 files changed
+127/−19 lines, 4 filesdep +bytestringdep +criteriondep +quickcheck-instancesdep ~QuickCheckdep ~basedep ~containersPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: bytestring, criterion, quickcheck-instances
Dependency ranges changed: QuickCheck, base, containers, hashable
API changes (from Hackage documentation)
+ Data.List.UniqueStrict: occurrences :: Ord a => [a] -> [(Int, [a])]
+ Data.List.UniqueUnsorted: occurrences :: (Hashable a, Eq a) => [a] -> [(Int, [a])]
Files
- Data/List/UniqueStrict.hs +18/−9
- Data/List/UniqueUnsorted.hs +13/−3
- Unique.cabal +29/−7
- bench/Main.hs +67/−0
Data/List/UniqueStrict.hs view
@@ -21,17 +21,19 @@ , unique , allUnique , count- , count_ )+ , count_+ , occurrences ) where import qualified Data.Map.Strict as MS (Map, filter, fromListWith, keys,- toList, lookup, map, foldr)--import qualified Data.IntMap.Strict as IM (fromListWith, toList)-+ toList, lookup, map, foldr')+import qualified Data.IntMap.Strict as IM (fromAscListWith, toList) import qualified Data.Set as DS (fromList, toList) +import Data.List (sortBy)+import Data.Function (on) + countMap :: Ord a => [a] -> MS.Map a Int countMap = MS.fromListWith (+) . flip zip (repeat 1) @@ -93,7 +95,7 @@ -- Since 0.4.7.2 allUnique :: Ord a => [a] -> Bool-allUnique = MS.foldr (&&) True . MS.map (==1) . countMap+allUnique = MS.foldr' (&&) True . MS.map (==1) . countMap -- | 'count' of each element in the list, it sorts by keys (elements). Example: --@@ -107,6 +109,13 @@ -- > count_ "foo bar" == [(' ',1),('a',1),('b',1),('f',1),('r',1),('o',2)] count_ :: Ord a => [a] -> [(a, Int)]-count_ = fromIntMap . toIntMap . MS.toList . countMap- where toIntMap = IM.fromListWith (++) . map (\(x,y) -> (y,[x]))- fromIntMap = concatMap (\(x,y) -> sortUniq . zip y $ repeat x) . IM.toList+count_ = sortBy (compare `on` snd) . MS.toList . countMap++-- | 'occurrences' like 'count' or 'count_' but shows the list of elements that occur X times+--+-- > occurrences "This is the test line" == [(1,"Tln"),(2,"h"),(3,"eist"),(4," ")]+-- Since 0.4.7.5+--++occurrences :: Ord a => [a] -> [(Int, [a])]+occurrences = IM.toList . IM.fromAscListWith (++) . map (\(k , x) -> (x, [k]) ) . count_
Data/List/UniqueUnsorted.hs view
@@ -24,6 +24,7 @@ , allUnique , count , count_+ , occurrences ) where @@ -33,7 +34,7 @@ import qualified Data.HashSet as DHS (toList, fromList) -import qualified Data.IntMap.Strict as IM (fromListWith, toList)+import qualified Data.IntMap.Strict as IM (fromAscListWith, fromListWith, toAscList) countMap :: (Hashable a, Eq a) => [a] -> HS.HashMap a Int@@ -112,5 +113,14 @@ count_ :: (Hashable a, Eq a) => [a] -> [(a, Int)] count_ = fromIntMap . toIntMap . HS.toList . countMap- where toIntMap = IM.fromListWith (++) . map (\(x,y) -> (y,[x]))- fromIntMap = concatMap (\(x,y) -> zip y $ repeat x) . IM.toList+ where toIntMap = IM.fromListWith (++) . map (\(x,y) -> (y,[x]))+ fromIntMap = concatMap (\(x,y) -> zip y $ repeat x) . IM.toAscList++-- | 'occurrences' like 'count' or 'count_' but shows the list of elements that occur X times+--+-- > occurrences "This is the test line" == [(1,"Tln"),(2,"h"),(3,"eist"),(4," ")]+-- Since 0.4.7.5+--++occurrences :: (Hashable a, Eq a) => [a] -> [(Int, [a])]+occurrences = IM.toAscList . IM.fromAscListWith (++) . map (\(k , x) -> (x, [k]) ) . count_
Unique.cabal view
@@ -1,6 +1,6 @@ name: Unique -version: 0.4.7.2+version: 0.4.7.5 synopsis: It provides the functionality like unix "uniq" utility description: Library provides the functions to find unique and duplicate elements in the list@@ -11,6 +11,12 @@ category: Data build-type: Simple cabal-version: >=1.10+tested-with: GHC == 8.4+ , GHC == 8.2+ , GHC == 8.0+ , GHC == 7.8+ , GHC == 7.6+ , GHC == 7.4 source-repository head type: git@@ -21,8 +27,8 @@ Data.List.UniqueStrict, Data.List.UniqueUnsorted - build-depends: base >= 4.0 && < 4.11- , containers >= 0.5.10 && < 0.6+ build-depends: base >= 4.0 && < 5+ , containers >= 0.5.0 && < 0.6 , extra >= 1.6.2 && < 1.7 , hashable >= 1.2.6 && < 1.3 , unordered-containers >= 0.2.8 && < 0.3@@ -49,13 +55,29 @@ , UniqueUnsorted.RemoveDuplicates , UniqueUnsorted.RepeatedBy , UniqueUnsorted.AllUnique- - build-depends: base >= 4.0 && < 4.11++ build-depends: base >= 4.0 && < 5 , hspec- , containers >= 0.5.10 && < 0.6- , QuickCheck+ , containers >= 0.5.0 && < 0.6+ , QuickCheck >= 2.10 && <2.12 , Unique default-language: Haskell2010 ghc-options: -Wall++Benchmark Criterion+ type: exitcode-stdio-1.0+ hs-source-dirs: bench+ main-is: Main.hs++ build-depends: base >= 4.0 && < 5+ , Unique+ , criterion+ , QuickCheck >= 2.10 && <2.12+ , quickcheck-instances+ , bytestring+ , hashable++ default-language: Haskell2010+ ghc-options: -Wall -rtsopts
+ bench/Main.hs view
@@ -0,0 +1,67 @@+{-# LANGUAGE RankNTypes #-}++import Criterion.Main+import Test.QuickCheck+import Test.QuickCheck.Instances()+import Data.ByteString.Lazy (ByteString)+import Data.Hashable++import qualified Data.List.Unique as U+import qualified Data.List.UniqueStrict as US+import qualified Data.List.UniqueUnsorted as UU+++setupEnv :: IO (Int, String, ByteString, [Int], [String], [ByteString])+setupEnv = do+ int <- generate (arbitrary :: Gen Int )+ string <- generate (arbitrary :: Gen String )+ bytestring <- generate (arbitrary :: Gen ByteString )+ ints <- generate (arbitrary :: Gen [Int] )+ strings <- generate (arbitrary :: Gen [String] )+ bytestrings <- generate (arbitrary :: Gen [ByteString] )+ return (int, string, bytestring, ints, strings, bytestrings )+++benchGroups :: (Hashable a, Ord a) => a -> [a] -> [Benchmark]+benchGroups x xs =+ [+ bgroup "isUnique" [ bench "Unique" $ whnf (U.isUnique x) xs+ , bench "UniqueStrict" $ whnf (US.isUnique x) xs+ , bench "UniqueUnsorted" $ whnf (UU.isUnique x) xs+ ]+ , bgroup "sortUniq" [ bench "Unique" $ whnf U.sortUniq xs+ , bench "UniqueStrict" $ whnf US.sortUniq xs+ , bench "UniqueUnsorted" $ whnf UU.removeDuplicates xs+ ]+ , bgroup "allUnique" [ bench "Unique" $ whnf U.allUnique xs+ , bench "UniqueStrict" $ whnf US.allUnique xs+ , bench "UniqueUnsorted" $ whnf UU.allUnique xs+ ]+ , bgroup "repeated" [ bench "Unique" $ whnf U.repeated xs+ , bench "UniqueStrict" $ whnf US.repeated xs+ , bench "UniqueUnsorted" $ whnf UU.repeated xs+ ]+ , bgroup "count" [ bench "Unique" $ whnf U.count xs+ , bench "UniqueStrict" $ whnf US.count xs+ , bench "UniqueUnsorted" $ whnf UU.count xs+ ]+ , bgroup "count_" [ bench "Unique" $ whnf U.count_ xs+ , bench "UniqueStrict" $ whnf US.count_ xs+ , bench "UniqueUnsorted" $ whnf UU.count_ xs+ ]+ , bgroup "occurrences" [ bench "Unique" $ whnf U.occurrences xs+ , bench "UniqueStrict" $ whnf US.occurrences xs+ , bench "UniqueUnsorted" $ whnf UU.occurrences xs+ ]+ ]++main :: IO ()+main = defaultMain [+ env setupEnv $ \ ~(int,st,byst,ints,sts,bysts) ->+ bgroup "Main" $+ [ bgroup "Int" $ benchGroups int ints+ , bgroup "String" $ benchGroups st sts+ , bgroup "ByteString" $ benchGroups byst bysts+ ]+ ]+