Unique 0.4.7.1 → 0.4.7.2
raw patch · 23 files changed
+750/−273 lines, 23 filesdep ~basedep ~containersdep ~extraPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependency ranges changed: base, containers, extra, hashable, unordered-containers
API changes (from Hackage documentation)
+ Data.List.UniqueStrict: allUnique :: Ord a => [a] -> Bool
+ Data.List.UniqueStrict: isRepeated :: Ord a => a -> [a] -> Maybe Bool
+ Data.List.UniqueStrict: isUnique :: Ord a => a -> [a] -> Maybe Bool
+ Data.List.UniqueStrict: sortUniq :: Ord a => [a] -> [a]
+ Data.List.UniqueUnsorted: allUnique :: (Hashable a, Eq a) => [a] -> Bool
+ Data.List.UniqueUnsorted: isRepeated :: (Hashable a, Eq a) => a -> [a] -> Maybe Bool
+ Data.List.UniqueUnsorted: isUnique :: (Hashable a, Eq a) => a -> [a] -> Maybe Bool
+ Data.List.UniqueUnsorted: removeDuplicates :: (Hashable a, Eq a) => [a] -> [a]
Files
- Data/List/Unique.hs +1/−1
- Data/List/UniqueStrict.hs +48/−6
- Data/List/UniqueUnsorted.hs +48/−3
- Unique.cabal +29/−19
- tests/AllUnique.hs +0/−33
- tests/Complex.hs +0/−26
- tests/IsUnique.hs +0/−70
- tests/Main.hs +30/−10
- tests/RepeatedBy.hs +0/−61
- tests/SortUniq.hs +0/−44
- tests/Unique/AllUnique.hs +33/−0
- tests/Unique/Complex.hs +26/−0
- tests/Unique/IsUnique.hs +70/−0
- tests/Unique/RepeatedBy.hs +61/−0
- tests/Unique/SortUniq.hs +44/−0
- tests/UniqueStrict/AllUnique.hs +33/−0
- tests/UniqueStrict/IsUnique.hs +54/−0
- tests/UniqueStrict/RepeatedBy.hs +61/−0
- tests/UniqueStrict/SortUniq.hs +44/−0
- tests/UniqueUnsorted/AllUnique.hs +33/−0
- tests/UniqueUnsorted/IsUnique.hs +54/−0
- tests/UniqueUnsorted/RemoveDuplicates.hs +30/−0
- tests/UniqueUnsorted/RepeatedBy.hs +51/−0
Data/List/Unique.hs view
@@ -1,7 +1,7 @@ ----------------------------------------------------------------------------- -- | -- Module : Data.List.Unique--- Copyright : (c) Volodymyr Yaschenko+-- Copyright : (c) Volodymyr Yashchenko -- License : BSD3 -- -- Maintainer : ualinuxcn@gmail.com
Data/List/UniqueStrict.hs view
@@ -1,7 +1,7 @@ ----------------------------------------------------------------------------- -- | -- Module : Data.List.UniqueStrict--- Copyright : (c) Volodymyr Yaschenko+-- Copyright : (c) Volodymyr Yashchenko -- License : BSD3 -- -- Maintainer : ualinuxcn@gmail.com@@ -13,24 +13,56 @@ -- So it's much faster and it uses less memory. module Data.List.UniqueStrict- (- repeated+ ( sortUniq+ , isUnique+ , isRepeated+ , repeated , repeatedBy , unique+ , allUnique , count , count_ ) where import qualified Data.Map.Strict as MS (Map, filter, fromListWith, keys,- toList)+ toList, lookup, map, foldr) import qualified Data.IntMap.Strict as IM (fromListWith, toList) -import qualified Data.List as L (sort)+import qualified Data.Set as DS (fromList, toList) + countMap :: Ord a => [a] -> MS.Map a Int countMap = MS.fromListWith (+) . flip zip (repeat 1) +-- | 'isUnique' function is to check whether the given element is unique in the list or not.+--+-- It returns Nothing when the element does not present in the list. Examples:+--+-- > isUnique 'f' "foo bar" == Just True+-- > isUnique 'o' "foo bar" == Just False+-- > isUnique '!' "foo bar" == Nothing+--+-- Since 0.4.7.2+--++isUnique :: Ord a => a -> [a] -> Maybe Bool+isUnique x = fmap (== 1) . MS.lookup x . countMap++-- | 'isRepeated' is a reverse function to 'isUnique'+--+-- Since 0.4.5++isRepeated :: Ord a => a -> [a] -> Maybe Bool+isRepeated x = fmap not . isUnique x++-- | 'sortUniq' sorts the list and removes the duplicates of elements. Example:+--+-- > sortUniq "foo bar" == " abfor"++sortUniq :: Ord a => [a] -> [a]+sortUniq = DS.toList . DS.fromList+ -- | The 'repeatedBy' function behaves just like repeated, except it uses a user-supplied equality predicate. -- -- > repeatedBy (>2) "This is the test line" == " eist"@@ -53,6 +85,16 @@ unique :: Ord a => [a] -> [a] unique = repeatedBy (==1) +-- | 'allUnique' checks whether all elements of the list are unique+--+-- > allUnique "foo bar" == False+-- > allUnique ['a'..'z'] == True+-- > allUnique [] == True (!)+-- Since 0.4.7.2++allUnique :: Ord a => [a] -> Bool+allUnique = MS.foldr (&&) True . MS.map (==1) . countMap+ -- | 'count' of each element in the list, it sorts by keys (elements). Example: -- -- > count "foo bar" == [(' ',1),('a',1),('b',1),('f',1),('o',2),('r',1)]@@ -67,4 +109,4 @@ 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) -> L.sort . zip y $ repeat x) . IM.toList+ fromIntMap = concatMap (\(x,y) -> sortUniq . zip y $ repeat x) . IM.toList
Data/List/UniqueUnsorted.hs view
@@ -1,7 +1,7 @@ ----------------------------------------------------------------------------- -- | -- Module : Data.List.UniqueUnsorted--- Copyright : (c) Volodymyr Yaschenko+-- Copyright : (c) Volodymyr Yashchenko -- License : BSD3 -- -- Maintainer : ualinuxcn@gmail.com@@ -15,9 +15,13 @@ -- This implementation is good for ByteStrings. module Data.List.UniqueUnsorted- ( repeated+ ( isUnique+ , isRepeated+ , removeDuplicates+ , repeated , repeatedBy , unique+ , allUnique , count , count_ )@@ -25,14 +29,44 @@ import Data.Hashable import qualified Data.HashMap.Strict as HS (HashMap, filter, fromListWith, keys,- toList)+ toList, lookup, map, foldr) +import qualified Data.HashSet as DHS (toList, fromList)+ import qualified Data.IntMap.Strict as IM (fromListWith, toList) countMap :: (Hashable a, Eq a) => [a] -> HS.HashMap a Int countMap = HS.fromListWith (+) . flip zip (repeat 1) +-- | 'isUnique' function is to check whether the given element is unique in the list or not.+--+-- It returns Nothing when the element does not present in the list. Examples:+--+-- > isUnique 'f' "foo bar" == Just True+-- > isUnique 'o' "foo bar" == Just False+-- > isUnique '!' "foo bar" == Nothing+--+-- Since 0.4.7.2+--++isUnique :: (Hashable a, Eq a) => a -> [a] -> Maybe Bool+isUnique x = fmap (== 1) . HS.lookup x . countMap++-- | 'isRepeated' is a reverse function to 'isUnique'+--+-- Since 0.4.7.2++isRepeated :: (Hashable a, Eq a) => a -> [a] -> Maybe Bool+isRepeated x = fmap not . isUnique x++-- | 'removeDuplicates' removes the duplicates of elements. Example:+--+-- > removeDuplicates "foo bar" == " abrfo"++removeDuplicates :: (Hashable a, Eq a) => [a] -> [a]+removeDuplicates = DHS.toList . DHS.fromList+ -- | The 'repeatedBy' function behaves just like 'repeated', except it uses a user-supplied equality predicate. -- -- > repeatedBy (>2) "This is the test line" == " stei"@@ -53,6 +87,17 @@ unique :: (Hashable a, Eq a) => [a] -> [a] unique = repeatedBy (==1)+++-- | 'allUnique' checks whether all elements of the list are unique+--+-- > allUnique "foo bar" == False+-- > allUnique ['a'..'z'] == True+-- > allUnique [] == True (!)+-- Since 0.4.7.2++allUnique :: (Hashable a, Eq a) => [a] -> Bool+allUnique = HS.foldr (&&) True . HS.map (==1) . countMap -- | 'count' of each element in the list. Example: --
Unique.cabal view
@@ -1,51 +1,61 @@ name: Unique -version: 0.4.7.1+version: 0.4.7.2 synopsis: It provides the functionality like unix "uniq" utility description: Library provides the functions to find unique and duplicate elements in the list license: BSD3 license-file: LICENSE-author: Volodymyr Yaschenko+author: Volodymyr Yashchenko maintainer: ualinuxcn@gmail.com category: Data build-type: Simple cabal-version: >=1.10 source-repository head- type: darcs- location: http://hub.darcs.net/kapral/Unique/+ type: git+ location: https://github.com/kapralVV/Unique.git library exposed-modules: Data.List.Unique, Data.List.UniqueStrict, Data.List.UniqueUnsorted - build-depends: base >=4.0 && < 5- , extra- , containers- , hashable- , unordered-containers+ build-depends: base >= 4.0 && < 4.11+ , containers >= 0.5.10 && < 0.6+ , extra >= 1.6.2 && < 1.7+ , hashable >= 1.2.6 && < 1.3+ , unordered-containers >= 0.2.8 && < 0.3+ default-language: Haskell2010- ghc-options: -Wall -O2+ ghc-options: -Wall Test-Suite HspecTest type: exitcode-stdio-1.0 hs-source-dirs: tests main-is: Main.hs- other-modules: Complex- , IsUnique- , RepeatedBy- , SortUniq- , AllUnique - build-depends: base >=4.0 && < 5+ other-modules: Unique.Complex+ , Unique.IsUnique+ , Unique.RepeatedBy+ , Unique.SortUniq+ , Unique.AllUnique+ , UniqueStrict.IsUnique+ , UniqueStrict.RepeatedBy+ , UniqueStrict.SortUniq+ , UniqueStrict.AllUnique+ , UniqueUnsorted.IsUnique+ , UniqueUnsorted.RemoveDuplicates+ , UniqueUnsorted.RepeatedBy+ , UniqueUnsorted.AllUnique+ ++ build-depends: base >= 4.0 && < 4.11 , hspec- , containers+ , containers >= 0.5.10 && < 0.6 , QuickCheck , Unique default-language: Haskell2010- ghc-options: -Wall -O2- + ghc-options: -Wall
− tests/AllUnique.hs
@@ -1,33 +0,0 @@-module AllUnique where--import Test.Hspec-import Test.QuickCheck-import Control.Exception (evaluate)-import Data.List (nub)--import Data.List.Unique---allUnique' :: Eq a => [a] -> Bool-allUnique' ls = (nub ls) == ls--allUniqueTests :: SpecWith ()-allUniqueTests =- describe "Data.List.Unique.allUnique" $ do- it "allUnique: returns True with empty list" $ do- allUnique "" `shouldBe` True-- it "allUnique: returns False when some element is not unique" $ do- allUnique "foo bar" `shouldBe` False-- it "allUnique: returns True when list does not have duplicates" $ do- allUnique ([1..1000] :: [Int]) `shouldBe` True-- it "allUnique: fails if list consist of duplicate elements and 'undefined' after them" $ do- evaluate (allUnique ['a', 'a', undefined] )- `shouldThrow`- errorCall "Prelude.undefined"-- it "allUnique: Test the function using slower analog and random data" $- property $- \ xs -> (allUnique' (xs :: String)) == (allUnique xs)
− tests/Complex.hs
@@ -1,26 +0,0 @@-module Complex where--import Test.Hspec-import Test.QuickCheck--import Data.List.Unique-import Data.List (sort)---triplet :: (a -> b) -> (a, a, a) -> (b, b, b)-triplet f (x, y, z) = (f x, f y, f z)--complexTests :: SpecWith ()-complexTests =- describe "Data.List.Unique.complex" $ do- - it "complex: should return ([],[],[]) with empty list" $ do- complex ( [] :: [Int] ) `shouldBe` ([],[],[])-- it "complex: simple test" $ do- complex "This is the test line" `shouldBe` ("This teln","is hte","Tln")-- it "complex: returns the same result as `sortUniq`, `repeated`, `unique` but not sorted" $- property $- \ xs -> triplet sort ( complex (xs :: String) )- == (sortUniq xs, repeated xs, unique xs)
− tests/IsUnique.hs
@@ -1,70 +0,0 @@-module IsUnique where--import Test.Hspec-import Test.QuickCheck-import Control.Exception (evaluate)-import Data.Maybe (isJust, isNothing)--import Data.List.Unique--isUniqueTests :: SpecWith ()-isUniqueTests =- describe "Data.List.Unique.isUnique" $ do- it "isUnique should return Nothing with empty list" $ do- isUnique (1 :: Int) [] - `shouldBe`- Nothing-- it "isUnique should return Nothing with empty list (quickCheck)" $- property $- \x -> isNothing $ isUnique (x :: Char) []-- it "isUnique, returns (Just True) when element is unique" $ do- isUnique 'a' "foo bar" `shouldBe` Just True-- it "isUnique , returns (Just False) when list has duplicate of element" $ do- isUnique 'o' "foo bar" `shouldBe` Just False-- it "isUnique is a lazy function, 'undefined test'" $ do- isUnique 'g' ['g','a','g', undefined ]- `shouldBe`- Just False-- it "isUnique is a lazy function, 'undefined test'. Generates exeption" $ do- evaluate (isUnique 't' ['t', 'd', undefined] )- `shouldThrow`- errorCall "Prelude.undefined"-- it "isRepeated is a lazy function too, 'undefined test'" $ do- isRepeated 'g' ['g','a','g', undefined ]- `shouldBe`- Just True-- it "isRepeated is reverse function to isUnique" $ do- property $- \ x xs- -> isUnique (x :: Int) xs == fmap not (isRepeated x xs)-- it "isUnique should return (Just ANY) when element is exist in the list" $- property $- \ ( NonEmpty ls@(x:_) )- -> isJust (isUnique (x :: Char) ls)-- context "isUnique should return (Just False) when at least two elements are exist in the list" $- it "- It checks laziness as well" $- property $- \ ( NonEmpty ls@(x:_) )- -> isJust $ isUnique (x :: Char) (ls ++ [x, undefined])-- it "isUnique should return Nothing when element is absent in the list" $- property $- \ x xs- -> notElem x xs- ==> isNothing (isUnique (x :: Char) xs)- - it "isUnique and isRepeated should return Nothing when element is absent in the list" $- property $- \ x xs- -> notElem x xs- ==> isNothing (isUnique (x :: Char) xs)- && isNothing (isRepeated x xs)
tests/Main.hs view
@@ -1,14 +1,34 @@-import IsUnique-import SortUniq-import RepeatedBy-import Complex-import AllUnique+import qualified Unique.IsUnique as U+import qualified Unique.SortUniq as U+import qualified Unique.RepeatedBy as U+import qualified Unique.Complex as U+import qualified Unique.AllUnique as U++import qualified UniqueStrict.IsUnique as US+import qualified UniqueStrict.SortUniq as US+import qualified UniqueStrict.RepeatedBy as US+import qualified UniqueStrict.AllUnique as US++import qualified UniqueUnsorted.IsUnique as UA+import qualified UniqueUnsorted.RemoveDuplicates as UA+import qualified UniqueUnsorted.RepeatedBy as UA+import qualified UniqueUnsorted.AllUnique as UA+ import Test.Hspec main :: IO ()-main = mapM_ hspec [isUniqueTests- , sortUniqTests- , repeatedByTests- , complexTests- , allUniqueTests+main = mapM_ hspec [ U.isUniqueTests+ , U.sortUniqTests+ , U.repeatedByTests+ , U.complexTests+ , U.allUniqueTests+ , US.isUniqueTests+ , US.sortUniqTests+ , US.repeatedByTests+ , US.allUniqueTests+ , UA.isUniqueTests+ , UA.removeDuplicatesTests+ , UA.repeatedByTests+ , UA.allUniqueTests ]+
− tests/RepeatedBy.hs
@@ -1,61 +0,0 @@-module RepeatedBy where--import Test.Hspec-import Test.QuickCheck--import Data.List.Unique-import Data.List (sort, group)---repeatedByTests :: SpecWith ()-repeatedByTests =- describe "Data.List.Unique.repeatedBy,repeated,unique" $ do- - it "repeatedBy: should return [] with empty list" $ do- repeatedBy (>100) ( [] :: [Int] ) `shouldBe` []-- it "repeatedBy: simple test" $ do- repeatedBy (>2) "This is the test line" `shouldBe` " eist"-- it "repeatedBy: returns [] when predicate (=< negative) " $- property $- \x xs -> x < 0- ==> null ( repeatedBy (<= x) (xs :: String) )-- it "repeatedBy: removes the duplicated elements like `sortUniq` function when predicate (>= negative)" $- property $- \ x xs -> x < 0- ==> repeatedBy (>= x) (xs :: String) == sortUniq xs-- it "repeatedBy: returns [] when preficate (== 0)" $- property $- \ xs -> null ( repeatedBy (== 0) (xs :: [Int]) )-- it "repeatedBy: returns sorted result" $- property $- \x xs -> x > 0- ==> repeatedBy (> x) (xs :: String) == sort (repeatedBy (> x) xs)-- it "repeatedBy: resulted elements should occur only once" $- property $- \ x xs -> x > 0- ==> all (==1) . map length . group $ repeatedBy (> x) ( xs :: String )-- it "unique: simple test" $ do- unique "foo bar" `shouldBe` " abfr"-- it "repeated: simple test" $ do- repeated "foo bar" `shouldBe` "o"-- it "unique: multiple execution should return the same result" $- property $- \ xs -> unique (xs :: String) == unique (unique xs)-- it "repeated: multiple execution should return []" $- property $- \ xs -> null (repeated (repeated (xs :: String) ))-- it "repeated && unique: should return different result on the same non empty list" $- property $- \ xs -> not (null xs)- ==> repeated (xs :: String) /= unique xs
− tests/SortUniq.hs
@@ -1,44 +0,0 @@-module SortUniq where--import Test.Hspec-import Test.QuickCheck--import Data.List.Unique-import Data.List (sort, group)-import Data.Set (fromList, toList)---sortUniqTests :: SpecWith ()-sortUniqTests =- describe "Data.List.Unique.sortUniq" $ do- - it "sortUniq: should return [] with empty list" $ do- sortUniq ( [] :: [Int] ) `shouldBe` []-- it "sortUniq: simple test" $ do- sortUniq "foo bar" `shouldBe` " abfor"-- it "sortUniq: multiple execution should return the same result" $- property $- \ xs -> sortUniq (sortUniq ( xs :: String) ) == sortUniq xs-- it "sortUniq: the result has to be sorted" $- property $- \ xs -> sortUniq ( xs :: [Int] ) == sort (sortUniq xs)-- it "sortUniq: elements should occur only once" $- property $- \ ( NonEmpty ls@(x:_) ) -> isUnique (x :: Float) (sortUniq ls) == Just True-- it "sortUniq: elements should occur only once #2" $- property $- \ xs -> all (==1) . map length . group $ sortUniq ( xs :: [Integer] )-- it "sortUniq: check if it's correct by slow analog function" $- property $- \ xs -> ( map head . group . sort $ (xs :: String) )- == sortUniq xs-- it "sortUniq: check if it's correct by the Faster analog function :)" $- property $- \ xs -> sortUniq ( xs :: String ) == toList (fromList xs)
+ tests/Unique/AllUnique.hs view
@@ -0,0 +1,33 @@+module Unique.AllUnique where++import Test.Hspec+import Test.QuickCheck+import Control.Exception (evaluate)+import Data.List (nub)++import Data.List.Unique+++allUnique' :: Eq a => [a] -> Bool+allUnique' ls = (nub ls) == ls++allUniqueTests :: SpecWith ()+allUniqueTests =+ describe "Data.List.Unique.allUnique" $ do+ it "allUnique: returns True with empty list" $ do+ allUnique "" `shouldBe` True++ it "allUnique: returns False when some element is not unique" $ do+ allUnique "foo bar" `shouldBe` False++ it "allUnique: returns True when list does not have duplicates" $ do+ allUnique ([1..1000] :: [Int]) `shouldBe` True++ it "allUnique: fails if list consist of duplicate elements and 'undefined' after them" $ do+ evaluate (allUnique ['a', 'a', undefined] )+ `shouldThrow`+ errorCall "Prelude.undefined"++ it "allUnique: Test the function using slower analog and random data" $+ property $+ \ xs -> (allUnique' (xs :: String)) == (allUnique xs)
+ tests/Unique/Complex.hs view
@@ -0,0 +1,26 @@+module Unique.Complex where++import Test.Hspec+import Test.QuickCheck++import Data.List.Unique+import Data.List (sort)+++triplet :: (a -> b) -> (a, a, a) -> (b, b, b)+triplet f (x, y, z) = (f x, f y, f z)++complexTests :: SpecWith ()+complexTests =+ describe "Data.List.Unique.complex" $ do+ + it "complex: should return ([],[],[]) with empty list" $ do+ complex ( [] :: [Int] ) `shouldBe` ([],[],[])++ it "complex: simple test" $ do+ complex "This is the test line" `shouldBe` ("This teln","is hte","Tln")++ it "complex: returns the same result as `sortUniq`, `repeated`, `unique` but not sorted" $+ property $+ \ xs -> triplet sort ( complex (xs :: String) )+ == (sortUniq xs, repeated xs, unique xs)
+ tests/Unique/IsUnique.hs view
@@ -0,0 +1,70 @@+module Unique.IsUnique where++import Test.Hspec+import Test.QuickCheck+import Control.Exception (evaluate)+import Data.Maybe (isJust, isNothing)++import Data.List.Unique++isUniqueTests :: SpecWith ()+isUniqueTests =+ describe "Data.List.Unique.isUnique" $ do+ it "isUnique: should return Nothing with empty list" $ do+ isUnique (1 :: Int) [] + `shouldBe`+ Nothing++ it "isUnique: should return Nothing with empty list (quickCheck)" $+ property $+ \x -> isNothing $ isUnique (x :: Char) []++ it "isUnique: returns (Just True) when element is unique" $ do+ isUnique 'a' "foo bar" `shouldBe` Just True++ it "isUnique: returns (Just False) when list has duplicate of element" $ do+ isUnique 'o' "foo bar" `shouldBe` Just False++ it "isUnique: is a lazy function, 'undefined test'" $ do+ isUnique 'g' ['g','a','g', undefined ]+ `shouldBe`+ Just False++ it "isUnique: is a lazy function, 'undefined test'. Generates exeption" $ do+ evaluate (isUnique 't' ['t', 'd', undefined] )+ `shouldThrow`+ errorCall "Prelude.undefined"++ it "isRepeated is a lazy function too, 'undefined test'" $ do+ isRepeated 'g' ['g','a','g', undefined ]+ `shouldBe`+ Just True++ it "isRepeated: is reverse function to isUnique" $ do+ property $+ \ x xs+ -> isUnique (x :: Int) xs == fmap not (isRepeated x xs)++ it "isUnique: should return (Just ANY) when element is exist in the list" $+ property $+ \ ( NonEmpty ls@(x:_) )+ -> isJust (isUnique (x :: Char) ls)++ context "isUnique: should return (Just False) when at least two elements are exist in the list" $+ it "- It checks laziness as well" $+ property $+ \ ( NonEmpty ls@(x:_) )+ -> isJust $ isUnique (x :: Char) (ls ++ [x, undefined])++ it "isUnique: should return Nothing when element is absent in the list" $+ property $+ \ x xs+ -> notElem x xs+ ==> isNothing (isUnique (x :: Char) xs)+ + it "isUnique: and isRepeated should return Nothing when element is absent in the list" $+ property $+ \ x xs+ -> notElem x xs+ ==> isNothing (isUnique (x :: Char) xs)+ && isNothing (isRepeated x xs)
+ tests/Unique/RepeatedBy.hs view
@@ -0,0 +1,61 @@+module Unique.RepeatedBy where++import Test.Hspec+import Test.QuickCheck++import Data.List.Unique+import Data.List (sort, group)+++repeatedByTests :: SpecWith ()+repeatedByTests =+ describe "Data.List.Unique.repeatedBy,repeated,unique" $ do+ + it "repeatedBy: should return [] with empty list" $ do+ repeatedBy (>100) ( [] :: [Int] ) `shouldBe` []++ it "repeatedBy: simple test" $ do+ repeatedBy (>2) "This is the test line" `shouldBe` " eist"++ it "repeatedBy: returns [] when predicate (=< negative) " $+ property $+ \x xs -> x < 0+ ==> null ( repeatedBy (<= x) (xs :: String) )++ it "repeatedBy: removes the duplicated elements like `sortUniq` function when predicate (>= negative)" $+ property $+ \ x xs -> x < 0+ ==> repeatedBy (>= x) (xs :: String) == sortUniq xs++ it "repeatedBy: returns [] when preficate (== 0)" $+ property $+ \ xs -> null ( repeatedBy (== 0) (xs :: [Int]) )++ it "repeatedBy: returns sorted result" $+ property $+ \x xs -> x > 0+ ==> repeatedBy (> x) (xs :: String) == sort (repeatedBy (> x) xs)++ it "repeatedBy: resulted elements should occur only once" $+ property $+ \ x xs -> x > 0+ ==> all (==1) . map length . group $ repeatedBy (> x) ( xs :: String )++ it "unique: simple test" $ do+ unique "foo bar" `shouldBe` " abfr"++ it "repeated: simple test" $ do+ repeated "foo bar" `shouldBe` "o"++ it "unique: multiple execution should return the same result" $+ property $+ \ xs -> unique (xs :: String) == unique (unique xs)++ it "repeated: multiple execution should return []" $+ property $+ \ xs -> null (repeated (repeated (xs :: String) ))++ it "repeated && unique: should return different result on the same non empty list" $+ property $+ \ xs -> not (null xs)+ ==> repeated (xs :: String) /= unique xs
+ tests/Unique/SortUniq.hs view
@@ -0,0 +1,44 @@+module Unique.SortUniq where++import Test.Hspec+import Test.QuickCheck++import Data.List.Unique+import Data.List (sort, group)+import Data.Set (fromList, toList)+++sortUniqTests :: SpecWith ()+sortUniqTests =+ describe "Data.List.Unique.sortUniq" $ do+ + it "sortUniq: should return [] with empty list" $ do+ sortUniq ( [] :: [Int] ) `shouldBe` []++ it "sortUniq: simple test" $ do+ sortUniq "foo bar" `shouldBe` " abfor"++ it "sortUniq: multiple execution should return the same result" $+ property $+ \ xs -> sortUniq (sortUniq ( xs :: String) ) == sortUniq xs++ it "sortUniq: the result has to be sorted" $+ property $+ \ xs -> sortUniq ( xs :: [Int] ) == sort (sortUniq xs)++ it "sortUniq: elements should occur only once" $+ property $+ \ ( NonEmpty ls@(x:_) ) -> isUnique (x :: Float) (sortUniq ls) == Just True++ it "sortUniq: elements should occur only once #2" $+ property $+ \ xs -> all (==1) . map length . group $ sortUniq ( xs :: [Integer] )++ it "sortUniq: check if it's correct by slow analog function" $+ property $+ \ xs -> ( map head . group . sort $ (xs :: String) )+ == sortUniq xs++ it "sortUniq: check if it's correct by the Faster analog function :)" $+ property $+ \ xs -> sortUniq ( xs :: String ) == toList (fromList xs)
+ tests/UniqueStrict/AllUnique.hs view
@@ -0,0 +1,33 @@+module UniqueStrict.AllUnique where++import Test.Hspec+import Test.QuickCheck+import Control.Exception (evaluate)+import Data.List (nub)++import Data.List.UniqueStrict+++allUnique' :: Eq a => [a] -> Bool+allUnique' ls = (nub ls) == ls++allUniqueTests :: SpecWith ()+allUniqueTests =+ describe "Data.List.UniqueStrict.allUnique" $ do+ it "allUnique: returns True with empty list" $ do+ allUnique "" `shouldBe` True++ it "allUnique: returns False when some element is not unique" $ do+ allUnique "foo bar" `shouldBe` False++ it "allUnique: returns True when list does not have duplicates" $ do+ allUnique ([1..1000] :: [Int]) `shouldBe` True++ it "allUnique: fails if list consist of duplicate elements and 'undefined' after them" $ do+ evaluate (allUnique ['a', 'a', undefined] )+ `shouldThrow`+ errorCall "Prelude.undefined"++ it "allUnique: Test the function using slower analog and random data" $+ property $+ \ xs -> (allUnique' (xs :: String)) == (allUnique xs)
+ tests/UniqueStrict/IsUnique.hs view
@@ -0,0 +1,54 @@+module UniqueStrict.IsUnique where++import Test.Hspec+import Test.QuickCheck+import Control.Exception (evaluate)+import Data.Maybe (isJust, isNothing)++import Data.List.UniqueStrict++isUniqueTests :: SpecWith ()+isUniqueTests =+ describe "Data.List.UniqueStrict.isUnique" $ do+ it "isUnique: should return Nothing with empty list" $ do+ isUnique (1 :: Int) [] + `shouldBe`+ Nothing++ it "isUnique: should return Nothing with empty list (quickCheck)" $+ property $+ \x -> isNothing $ isUnique (x :: Char) []++ it "isUnique: returns (Just True) when element is unique" $ do+ isUnique 'a' "foo bar" `shouldBe` Just True++ it "isUnique: returns (Just False) when list has duplicate of element" $ do+ isUnique 'o' "foo bar" `shouldBe` Just False++ it "isUnique: is NOT a lazy function, 'undefined test'" $ do+ evaluate (isUnique 'g' ['g','a','g', undefined ])+ `shouldThrow`+ errorCall "Prelude.undefined"+ + it "isRepeated: is reverse function to isUnique" $ do+ property $+ \ x xs+ -> isUnique (x :: Int) xs == fmap not (isRepeated x xs)++ it "isUnique: should return (Just ANY) when element is exist in the list" $+ property $+ \ ( NonEmpty ls@(x:_) )+ -> isJust (isUnique (x :: Char) ls)++ it "isUnique: should return Nothing when element is absent in the list" $+ property $+ \ x xs+ -> notElem x xs+ ==> isNothing (isUnique (x :: Char) xs)+ + it "isUnique: and isRepeated should return Nothing when element is absent in the list" $+ property $+ \ x xs+ -> notElem x xs+ ==> isNothing (isUnique (x :: Char) xs)+ && isNothing (isRepeated x xs)
+ tests/UniqueStrict/RepeatedBy.hs view
@@ -0,0 +1,61 @@+module UniqueStrict.RepeatedBy where++import Test.Hspec+import Test.QuickCheck++import Data.List.UniqueStrict+import Data.List (sort, group)+++repeatedByTests :: SpecWith ()+repeatedByTests =+ describe "Data.List.UniqueStrict.repeatedBy,repeated,unique" $ do+ + it "repeatedBy: should return [] with empty list" $ do+ repeatedBy (>100) ( [] :: [Int] ) `shouldBe` []++ it "repeatedBy: simple test" $ do+ repeatedBy (>2) "This is the test line" `shouldBe` " eist"++ it "repeatedBy: returns [] when predicate (=< negative) " $+ property $+ \x xs -> x < 0+ ==> null ( repeatedBy (<= x) (xs :: String) )++ it "repeatedBy: removes the duplicated elements like `sortUniq` function when predicate (>= negative)" $+ property $+ \ x xs -> x < 0+ ==> repeatedBy (>= x) (xs :: String) == sortUniq xs++ it "repeatedBy: returns [] when preficate (== 0)" $+ property $+ \ xs -> null ( repeatedBy (== 0) (xs :: [Int]) )++ it "repeatedBy: returns sorted result" $+ property $+ \x xs -> x > 0+ ==> repeatedBy (> x) (xs :: String) == sort (repeatedBy (> x) xs)++ it "repeatedBy: resulted elements should occur only once" $+ property $+ \ x xs -> x > 0+ ==> all (==1) . map length . group $ repeatedBy (> x) ( xs :: String )++ it "unique: simple test" $ do+ unique "foo bar" `shouldBe` " abfr"++ it "repeated: simple test" $ do+ repeated "foo bar" `shouldBe` "o"++ it "unique: multiple execution should return the same result" $+ property $+ \ xs -> unique (xs :: String) == unique (unique xs)++ it "repeated: multiple execution should return []" $+ property $+ \ xs -> null (repeated (repeated (xs :: String) ))++ it "repeated && unique: should return different result on the same non empty list" $+ property $+ \ xs -> not (null xs)+ ==> repeated (xs :: String) /= unique xs
+ tests/UniqueStrict/SortUniq.hs view
@@ -0,0 +1,44 @@+module UniqueStrict.SortUniq where++import Test.Hspec+import Test.QuickCheck++import Data.List.UniqueStrict+import Data.List (sort, group)+import Data.Set (fromList, toList)+++sortUniqTests :: SpecWith ()+sortUniqTests =+ describe "Data.List.UniqueStrict.sortUniq" $ do+ + it "sortUniq: should return [] with empty list" $ do+ sortUniq ( [] :: [Int] ) `shouldBe` []++ it "sortUniq: simple test" $ do+ sortUniq "foo bar" `shouldBe` " abfor"++ it "sortUniq: multiple execution should return the same result" $+ property $+ \ xs -> sortUniq (sortUniq ( xs :: String) ) == sortUniq xs++ it "sortUniq: the result has to be sorted" $+ property $+ \ xs -> sortUniq ( xs :: [Int] ) == sort (sortUniq xs)++ it "sortUniq: elements should occur only once" $+ property $+ \ ( NonEmpty ls@(x:_) ) -> isUnique (x :: Float) (sortUniq ls) == Just True++ it "sortUniq: elements should occur only once #2" $+ property $+ \ xs -> all (==1) . map length . group $ sortUniq ( xs :: [Integer] )++ it "sortUniq: check if it's correct by slow analog function" $+ property $+ \ xs -> ( map head . group . sort $ (xs :: String) )+ == sortUniq xs++ it "sortUniq: check if it's correct by the Faster analog function :)" $+ property $+ \ xs -> sortUniq ( xs :: String ) == toList (fromList xs)
+ tests/UniqueUnsorted/AllUnique.hs view
@@ -0,0 +1,33 @@+module UniqueUnsorted.AllUnique where++import Test.Hspec+import Test.QuickCheck+import Control.Exception (evaluate)+import Data.List (nub)++import Data.List.UniqueUnsorted+++allUnique' :: Eq a => [a] -> Bool+allUnique' ls = (nub ls) == ls++allUniqueTests :: SpecWith ()+allUniqueTests =+ describe "Data.List.UniqueUnsorted.allUnique" $ do+ it "allUnique: returns True with empty list" $ do+ allUnique "" `shouldBe` True++ it "allUnique: returns False when some element is not unique" $ do+ allUnique "foo bar" `shouldBe` False++ it "allUnique: returns True when list does not have duplicates" $ do+ allUnique ([1..1000] :: [Int]) `shouldBe` True++ it "allUnique: fails if list consist of duplicate elements and 'undefined' after them" $ do+ evaluate (allUnique ['a', 'a', undefined] )+ `shouldThrow`+ errorCall "Prelude.undefined"++ it "allUnique: Test the function using slower analog and random data" $+ property $+ \ xs -> (allUnique' (xs :: String)) == (allUnique xs)
+ tests/UniqueUnsorted/IsUnique.hs view
@@ -0,0 +1,54 @@+module UniqueUnsorted.IsUnique where++import Test.Hspec+import Test.QuickCheck+import Control.Exception (evaluate)+import Data.Maybe (isJust, isNothing)++import Data.List.UniqueUnsorted++isUniqueTests :: SpecWith ()+isUniqueTests =+ describe "Data.List.UniqueUnsorted.isUnique" $ do+ it "isUnique: should return Nothing with empty list" $ do+ isUnique (1 :: Int) [] + `shouldBe`+ Nothing++ it "isUnique: should return Nothing with empty list (quickCheck)" $+ property $+ \x -> isNothing $ isUnique (x :: Char) []++ it "isUnique: returns (Just True) when element is unique" $ do+ isUnique 'a' "foo bar" `shouldBe` Just True++ it "isUnique: returns (Just False) when list has duplicate of element" $ do+ isUnique 'o' "foo bar" `shouldBe` Just False++ it "isUnique: is NOT a lazy function, 'undefined test'" $ do+ evaluate (isUnique 'g' ['g','a','g', undefined ])+ `shouldThrow`+ errorCall "Prelude.undefined"+ + it "isRepeated: is reverse function to isUnique" $ do+ property $+ \ x xs+ -> isUnique (x :: Int) xs == fmap not (isRepeated x xs)++ it "isUnique: should return (Just ANY) when element is exist in the list" $+ property $+ \ ( NonEmpty ls@(x:_) )+ -> isJust (isUnique (x :: Char) ls)++ it "isUnique: should return Nothing when element is absent in the list" $+ property $+ \ x xs+ -> notElem x xs+ ==> isNothing (isUnique (x :: Char) xs)+ + it "isUnique: and isRepeated should return Nothing when element is absent in the list" $+ property $+ \ x xs+ -> notElem x xs+ ==> isNothing (isUnique (x :: Char) xs)+ && isNothing (isRepeated x xs)
+ tests/UniqueUnsorted/RemoveDuplicates.hs view
@@ -0,0 +1,30 @@+module UniqueUnsorted.RemoveDuplicates where++import Test.Hspec+import Test.QuickCheck++import Data.List.UniqueUnsorted+import Data.List (group)+++removeDuplicatesTests :: SpecWith ()+removeDuplicatesTests =+ describe "Data.List.UniqueUnsorted.removeDuplicates" $ do+ + it "removeDuplicates: should return [] with empty list" $ do+ removeDuplicates ( [] :: [Int] ) `shouldBe` []++ it "removeDuplicates: simple test" $ do+ removeDuplicates "foo bar" `shouldBe` " abrfo"++ it "removeDuplicates: multiple execution should return the same result" $+ property $+ \ xs -> removeDuplicates (removeDuplicates ( xs :: String) ) == removeDuplicates xs++ it "removeDuplicates: elements should occur only once" $+ property $+ \ ( NonEmpty ls@(x:_) ) -> isUnique (x :: Float) (removeDuplicates ls) == Just True++ it "removeDuplicates: elements should occur only once #2" $+ property $+ \ xs -> all (==1) . map length . group $ removeDuplicates ( xs :: [Integer] )
+ tests/UniqueUnsorted/RepeatedBy.hs view
@@ -0,0 +1,51 @@+module UniqueUnsorted.RepeatedBy where++import Test.Hspec+import Test.QuickCheck++import Data.List.UniqueUnsorted+import Data.List (group)+++repeatedByTests :: SpecWith ()+repeatedByTests =+ describe "Data.List.UniqueUnsorted.repeatedBy,repeated,unique" $ do+ + it "repeatedBy: should return [] with empty list" $ do+ repeatedBy (>100) ( [] :: [Int] ) `shouldBe` []++ it "repeatedBy: simple test" $ do+ repeatedBy (>2) "This is the test line" `shouldBe` " stei"++ it "repeatedBy: returns [] when predicate (=< negative) " $+ property $+ \x xs -> x < 0+ ==> null ( repeatedBy (<= x) (xs :: String) )++ it "repeatedBy: returns [] when preficate (== 0)" $+ property $+ \ xs -> null ( repeatedBy (== 0) (xs :: [Int]) )++ it "repeatedBy: resulted elements should occur only once" $+ property $+ \ x xs -> x > 0+ ==> all (==1) . map length . group $ repeatedBy (> x) ( xs :: String )++ it "unique: simple test" $ do+ unique "foo bar" `shouldBe` " abrf"++ it "repeated: simple test" $ do+ repeated "foo bar" `shouldBe` "o"++ it "unique: multiple execution should return the same result" $+ property $+ \ xs -> unique (xs :: String) == unique (unique xs)++ it "repeated: multiple execution should return []" $+ property $+ \ xs -> null (repeated (repeated (xs :: String) ))++ it "repeated && unique: should return different result on the same non empty list" $+ property $+ \ xs -> not (null xs)+ ==> repeated (xs :: String) /= unique xs