packages feed

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 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