packages feed

classy-prelude 0.5.2 → 0.5.3

raw patch · 12 files changed

+305/−2 lines, 12 filesdep ~basic-preludePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: basic-prelude

API changes (from Hackage documentation)

+ ClassyPrelude: data Seq a :: * -> *
+ ClassyPrelude: group :: CanGroup c a => c -> [c]
+ ClassyPrelude: groupBy :: CanGroupBy c a => (a -> a -> Bool) -> c -> [c]
+ ClassyPrelude: groupWith :: (CanGroupBy c a, Eq b) => (a -> b) -> c -> [c]
+ ClassyPrelude: product :: (Foldable t, Num a) => t a -> a
+ ClassyPrelude: repeat :: CanRepeat c a => a -> c
+ ClassyPrelude: sum :: (Foldable t, Num a) => t a -> a
+ ClassyPrelude.Classes: class CanGroup c a | c -> a where group = groupBy (==)
+ ClassyPrelude.Classes: class CanGroupBy c a | c -> a
+ ClassyPrelude.Classes: class CanRepeat c a | c -> a
+ ClassyPrelude.Classes: group :: CanGroup c a => c -> [c]
+ ClassyPrelude.Classes: groupBy :: CanGroupBy c a => (a -> a -> Bool) -> c -> [c]
+ ClassyPrelude.Classes: repeat :: CanRepeat c a => a -> c

Files

ClassyPrelude.hs view
@@ -6,6 +6,7 @@ module ClassyPrelude     ( -- * CorePrelude       module CorePrelude+    , Seq       -- * Standard       -- ** Monoid     , empty@@ -69,9 +70,15 @@     , sort     , sortBy     , sortWith+    , group+    , groupBy+    , groupWith     , cons     , uncons     , compareLength+    , Foldable.sum+    , Foldable.product+    , repeat       -- ** Map-like     , lookup     , insert@@ -143,6 +150,7 @@ import ClassyPrelude.Set () import ClassyPrelude.Text () import ClassyPrelude.Vector ()+import ClassyPrelude.Sequence (Seq)   show :: (Show a, CanPack c Char) => a -> c@@ -257,3 +265,11 @@ -- Inspired by <http://hackage.haskell.org/packages/archive/base/latest/doc/html/GHC-Exts.html#v:sortWith>. sortWith :: (CanSortBy c a, Ord b) => (a -> b) -> c -> c sortWith f = sortBy $ comparing f++-- | The 'groupWith' function uses the user supplied function which+-- projects an element out of every list element in order to first sort the+-- input list and then to form groups by equality on these projected elements+--+-- Inspired by <http://hackage.haskell.org/packages/archive/base/latest/doc/html/GHC-Exts.html#v:groupWith>+groupWith :: (CanGroupBy c a, Eq b) => (a -> b) -> c -> [c]+groupWith f = groupBy (\a b -> f a == f b)
ClassyPrelude/ByteString.hs view
@@ -37,6 +37,13 @@ instance CanIntersperse ByteString Word8 where     intersperse = ByteString.intersperse +instance CanStripPrefix ByteString where+    stripPrefix x y+        | x `ByteString.isPrefixOf` y =+            Just $ ByteString.drop (ByteString.length x) y+        | otherwise = Nothing+    isPrefixOf = ByteString.isPrefixOf+ instance CanReadFile ByteString where     readFile = liftIO . ByteString.readFile . FilePath.encodeString @@ -71,6 +78,9 @@         | otherwise = Nothing     isSuffixOf = ByteString.isSuffixOf +instance CanIsInfixOf ByteString where+    isInfixOf = ByteString.isInfixOf+ instance MonadIO m => CanGetLine (m ByteString) where     getLine = liftIO ByteString.getLine @@ -82,3 +92,9 @@  instance CanUncons ByteString Word8 where     uncons = ByteString.uncons++instance CanGroupBy ByteString Word8 where+    groupBy = ByteString.groupBy++instance CanGroup ByteString Word8 where+    group = ByteString.group
ClassyPrelude/Classes.hs view
@@ -203,3 +203,14 @@     -- or `Text`. It does not traverse the whole data structure if the value     -- being compared to is lesser.     compareLength :: (Integral l) => c -> l -> Ordering++class CanGroupBy c a | c -> a where+    groupBy :: (a -> a -> Bool) -> c -> [c]++class CanGroup c a | c -> a where+    group :: c -> [c]+    default group :: (CanGroupBy c a, Eq a) => c -> [c]+    group = groupBy (==)++class CanRepeat c a | c -> a where+    repeat :: a -> c
ClassyPrelude/LByteString.hs view
@@ -38,6 +38,13 @@ instance CanIntersperse LByteString Word8 where     intersperse = LByteString.intersperse +instance CanStripPrefix LByteString where+    stripPrefix x y+        | x `LByteString.isPrefixOf` y =+            Just $ LByteString.drop (LByteString.length x) y+        | otherwise = Nothing+    isPrefixOf = LByteString.isPrefixOf+ instance CanReadFile LByteString where     readFile = liftIO . LByteString.readFile . FilePath.encodeString @@ -88,3 +95,12 @@  instance CanUncons LByteString Word8 where     uncons = LByteString.uncons++instance CanGroupBy LByteString Word8 where+    groupBy = LByteString.groupBy++instance CanGroup LByteString Word8 where+    group = LByteString.group++instance CanRepeat LByteString Word8 where+    repeat = LByteString.repeat
ClassyPrelude/LText.hs view
@@ -125,3 +125,9 @@  instance CanCompareLength LText where     compareLength c = LText.compareLength c . fromIntegral++instance CanGroupBy LText Char where+    groupBy = LText.groupBy++instance CanGroup LText Char where+    group = LText.group
ClassyPrelude/List.hs view
@@ -148,3 +148,12 @@     compareLength _ i | i <= 0 = GT     compareLength [] _ = LT     compareLength (_:t) i = compareLength t (i-1)++instance CanGroupBy [a] a where+    groupBy = List.groupBy++instance Eq a => CanGroup [a] a where+    group = List.group++instance CanRepeat [a] a where+    repeat = List.repeat
+ ClassyPrelude/Sequence.hs view
@@ -0,0 +1,135 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeFamilies #-}+module ClassyPrelude.Sequence+    ( Seq+    ) where++import CorePrelude+import ClassyPrelude.Classes+import qualified Data.Monoid as Monoid+import qualified Control.Monad as Monad+import qualified Data.Foldable as Foldable+import qualified Data.Traversable as Traversable+import qualified Data.Sequence as Sequence+import Data.Sequence (Seq, (<|), (|>), ViewL(..), viewl, ViewR(..), viewr)+++instance CanMap (Seq a) (Seq b) a b where+    map = Monad.fmap++instance CanConcatMap (Seq a) (Seq b) a (Seq b) where+    concatMap = (Monad.=<<)++instance CanFilter (Seq a) a where+    filter = Sequence.filter++instance CanFilterM (Seq a) a where+    filterM p =+        Foldable.foldlM+            (\ xs x -> do res <- p x; return $ if res then xs |> x else xs)+            Sequence.empty++instance CanLength (Seq a) Int where+    length = Sequence.length++instance CanSingleton (Seq a) a where+    singleton = Sequence.singleton++instance CanNull (Seq a) where+    null = Sequence.null++instance CanPack (Seq a) a where+    pack = Sequence.fromList+    unpack = Foldable.toList++instance CanIntersperse (Seq a) a where+    intersperse sep xs = case viewl xs of+        EmptyL -> Sequence.empty+        (h :< t) -> h <| prependToAll sep t+      where+        prependToAll sep xs = case viewl xs of+            EmptyL -> Sequence.empty+            (h :< t) -> sep <| (h <| prependToAll sep t)++instance Eq a => CanStripPrefix (Seq a) where+    stripPrefix x y+        | x == y1 = Just y2+        | otherwise = Nothing+      where+        (y1, y2) = Sequence.splitAt (Sequence.length x) y+    isPrefixOf x y = Sequence.take (Sequence.length x) y == x++instance Eq a => CanStripSuffix (Seq a) where+    stripSuffix x y+        | x == y2 = Just y1+        | otherwise = Nothing+      where+        (y1, y2) = Sequence.splitAt (Sequence.length y - Sequence.length x) y+    isSuffixOf x y = takeRR (Sequence.length x) y == x+      where+        takeRR 0 _ = Sequence.empty+        takeRR n xs = case viewr xs of+            EmptyR -> Sequence.empty+            xs' :> x -> takeRR (n-1) xs' |> x++instance Monad m => CanMapM (Seq i) (m (Seq o)) m i o where+    mapM = Traversable.mapM++instance CanMapM_ (Seq a) a where+    mapM_ = Foldable.mapM_++instance Eq x => CanMember (Seq x) x where+    member x = any (== x)++instance CanBreak (Seq a) a where+    break = Sequence.breakl+    span = Sequence.spanl+    dropWhile = Sequence.dropWhileL+    takeWhile = Sequence.takeWhileL++instance CanAny (Seq a) a where+    any = Foldable.any+    all = Foldable.all++instance CanSplitAt (Seq a) Int where+    splitAt = Sequence.splitAt++instance CanFold (Seq a) a accum where+    fold = Foldable.foldl'++instance CanReverse (Seq a) where+    reverse = Sequence.reverse++instance CanReplicate (Seq a) a Int where+    replicate = Sequence.replicate++instance CanReplicateM (Seq a) a Int where+    replicateM = Sequence.replicateM++instance CanFind (Seq a) a where+    find p s = case Sequence.breakl p s of+        (_, s') -> case Sequence.viewl s' of+            a :< _ -> Just a+            _ -> Nothing++instance (Monoid m) => CanConcat (Seq m) m where+    concat = Foldable.fold++instance CanPartition (Seq a) a where+    partition = Sequence.partition++instance CanSortBy (Seq a) a where+    sortBy = Sequence.sortBy++instance Ord a => CanSort (Seq a) a where+    sort = Sequence.sort++instance CanCons (Seq a) a where+    cons = (<|)++instance CanUncons (Seq a) a where+    uncons s = case Sequence.viewl s of+        EmptyL -> Nothing+        a :< s' -> Just (a, s')
ClassyPrelude/Set.hs view
@@ -16,6 +16,9 @@ instance (Ord a, Ord b) => CanMap (Set a) (Set b) a b where     map = Set.map +instance Ord a => CanFilter (Set a) a where+    filter = Set.filter+ instance CanLength (Set x) Int where     length = Set.size @@ -31,6 +34,9 @@  instance (Ord x, Set x ~ s, x ~ x') => CanInsert (x' -> s -> Set x) where     insert = Set.insert++instance Ord x => CanDeleteVal (Set x) x where+    deleteVal = Set.delete  instance Ord x => CanMember (Set x) x where     member = Set.member
ClassyPrelude/Text.hs view
@@ -117,3 +117,9 @@  instance CanCompareLength Text where     compareLength c = Text.compareLength c . fromIntegral++instance CanGroupBy Text Char where+    groupBy = Text.groupBy++instance CanGroup Text Char where+    group = Text.group
ClassyPrelude/Vector.hs view
@@ -45,6 +45,14 @@         prependToAll _ xs | null xs = Vector.empty         prependToAll sep xs = Vector.cons sep $ Vector.cons (Vector.head xs) $ prependToAll sep $ Vector.unsafeTail xs +instance Eq a => CanStripPrefix (Vector a) where+    stripPrefix x y+        | x == y1 = Just y2+        | otherwise = Nothing+      where+        (y1, y2) = Vector.splitAt (Vector.length x) y+    isPrefixOf x y = Vector.take (Vector.length x) y == x+ instance Monad m => CanMapM (Vector i) (m (Vector o)) m i o where     mapM = Vector.mapM @@ -93,3 +101,39 @@  instance CanUncons (Vector a) a where     uncons v = if null v then Nothing else Just (Vector.unsafeHead v, Vector.unsafeTail v)++instance CanGroupBy (Vector a) a where+    -- | Implementation is stolen from <http://hackage.haskell.org/packages/archive/storablevector/latest/doc/html/src/Data-StorableVector.html#groupBy>+    groupBy k xs =+      switchL []+        (\h t ->+          let n = 1 + findIndexOrEnd (not . k h) t+          in  Vector.unsafeTake n xs : groupBy k (Vector.unsafeDrop n xs))+        xs++instance Eq a => CanGroup (Vector a) a where+    -- | A special case of 'groupBy', which is about 40% faster than +    -- /groupBy (==)/.+    -- +    -- Implementation is stolen from <http://hackage.haskell.org/packages/archive/storablevector/latest/doc/html/src/Data-StorableVector.html#groupBy>+    group xs =+      switchL []+        (\h _ ->+          let (ys, zs) = span (== h) xs+          in  ys : group zs)+        xs++-- Helper functions stolen from <http://hackage.haskell.org/packages/archive/storablevector/latest/doc/html/src/Data-StorableVector.html#groupBy>++-- | 'findIndexOrEnd' is a variant of findIndex, that returns the length+-- of the string if no element is found, rather than Nothing.+findIndexOrEnd p xs =+  Vector.foldr+    (\x k n ->+       if p x then n else k (succ n))+    id xs 0+switchL n j x =+  if null x+    then n+    else j (Vector.unsafeHead x) (Vector.unsafeTail x)+
classy-prelude.cabal view
@@ -1,5 +1,5 @@ name:                classy-prelude-version:             0.5.2+version:             0.5.3 synopsis:            A typeclass-based Prelude. description:         Focuses on using common typeclasses when possible, and creating new ones to avoid name clashing. Exposes many recommended datastructures (Map, ByteString, etc) directly without requiring long import lists and qualified modules. homepage:            https://github.com/snoyberg/classy-prelude@@ -27,8 +27,9 @@                        ClassyPrelude.HashMap                        ClassyPrelude.HashSet                        ClassyPrelude.Char+                       ClassyPrelude.Sequence   build-depends:       base                          >= 4          && < 5-                     , basic-prelude                 >= 0.3.3      && < 0.4+                     , basic-prelude                 >= 0.3.4      && < 0.4                      , system-filepath               >= 0.4        && < 0.5                      , transformers                      , containers                    >= 0.4.2
test/main.hs view
@@ -243,6 +243,21 @@     prop "compare (length c) i == compareLength c i" $ \i c ->         compare (length c) i == compareLength (c `asTypeOf` dummy) i +prefixProps :: ( Show c+               , Eq c+               , Monoid c+               , CanStripPrefix c+               , Arbitrary c+               )+            => c -> Spec+prefixProps dummy = do+    prop "x `isPrefixOf` (x ++ y)" $ \x y ->+        (x `asTypeOf` dummy) `isPrefixOf` (x ++ y)+    prop "stripPrefix x (x ++ y) == Just y" $ \x y ->+        stripPrefix x (x ++ y) == Just (y `asTypeOf` dummy)+    prop "stripPrefix x y == Nothing || x `isPrefixOf` y" $ \x y ->+        stripPrefix x y == Nothing || x `isPrefixOf` (y `asTypeOf` dummy)+ main :: IO () main = hspec $ do     describe "dictionary" $ do@@ -258,6 +273,7 @@         describe "Data.ByteString.Lazy" $ mapProps (undefined :: LByteString) (+ 1) (+ 2)         describe "Data.Text" $ mapProps (undefined :: Text) succ succ         describe "Data.Text.Lazy" $ mapProps (undefined :: LText) succ succ+        describe "Data.Sequence" $ mapProps (undefined :: Seq Int) succ succ     describe "concatMap" $ do         describe "list" $ concatMapProps (undefined :: [Int]) (\i -> [i + 1, i + 2])         describe "Data.Vector" $ concatMapProps (undefined :: Vector Int) (\i -> fromList [i + 1, i + 2])@@ -265,6 +281,7 @@         describe "Data.ByteString.Lazy" $ concatMapProps (undefined :: LByteString) (\i -> fromList [i + 1, i + 2])         describe "Data.Text" $ concatMapProps (undefined :: Text) (\c -> pack [succ c, succ $ succ c])         describe "Data.Text.Lazy" $ concatMapProps (undefined :: LText) (\c -> pack [succ c, succ $ succ c])+        describe "Data.Sequence" $ concatMapProps (undefined :: Seq Int) (\i -> pack [i + 1, i + 2])     describe "filter" $ do         describe "list" $ filterProps (undefined :: [Int]) (< 20)         describe "Data.Vector" $ filterProps (undefined :: Vector Int) (< 20)@@ -274,9 +291,12 @@         describe "Data.Text.Lazy" $ filterProps (undefined :: LText) (< 'A')         describe "Data.Map" $ filterProps (undefined :: Map Int Char) (\(i, _) -> i < 20)         describe "Data.HashMap" $ filterProps (undefined :: HashMap Int Char) (\(i, _) -> i < 20)+        describe "Data.Set" $ filterProps (undefined :: Set Int) (< 20)+        describe "Data.Sequence" $ filterProps (undefined :: Seq Int) (< 20)     describe "filterM" $ do         describe "list" $ filterMProps (undefined :: [Int]) (< 20)         describe "Data.Vector" $ filterMProps (undefined :: Vector Int) (< 20)+        describe "Data.Sequence" $ filterMProps (undefined :: Seq Int) (< 20)     describe "length" $ do         describe "list" $ lengthProps (undefined :: [Int])         describe "Data.Vector" $ lengthProps (undefined :: Vector Int)@@ -288,14 +308,17 @@         describe "Data.HashMap" $ lengthProps (undefined :: HashMap Int Char)         describe "Data.Set" $ lengthProps (undefined :: Set Int)         describe "Data.HashSet" $ lengthProps (undefined :: HashSet Int)+        describe "Data.Sequence" $ lengthProps (undefined :: Seq Int)     describe "mapM" $ do         describe "list" $ mapMProps (undefined :: [Int])         describe "Data.Vector" $ mapMProps (undefined :: Vector Int)+        describe "Seq" $ mapMProps (undefined :: Seq Int)     describe "mapM_" $ do         describe "list" $ mapM_Props (undefined :: [Int])         describe "Data.Vector" $ mapM_Props (undefined :: Vector Int)         describe "Set" $ mapM_Props (undefined :: Set Int)         describe "HashSet" $ mapM_Props (undefined :: HashSet Int)+        describe "Seq" $ mapM_Props (undefined :: Seq Int)     describe "fold" $ do         let f = flip (:)         describe "list" $ foldProps (undefined :: [Int]) f []@@ -306,6 +329,7 @@         describe "Data.Text.Lazy" $ foldProps (undefined :: LText) f []         describe "Data.Set" $ foldProps (undefined :: Set Int) f []         describe "Data.HashSet" $ foldProps (undefined :: HashSet Int) f []+        describe "Data.Sequence" $ foldProps (undefined :: Seq Int) f []     describe "replicate" $ do         describe "list" $ replicateProps (undefined :: [Int]) pack         describe "Data.Vector" $ replicateProps (undefined :: Vector Int) pack@@ -313,6 +337,7 @@         describe "Data.ByteString.Lazy" $ replicateProps (undefined :: LByteString) pack         describe "Data.Text" $ replicateProps (undefined :: Text) concat         describe "Data.Text.Lazy" $ replicateProps (undefined :: LText) concat+        describe "Data.Sequence" $ replicateProps (undefined :: Seq Int) pack     describe "chunks" $ do         describe "ByteString" $ chunkProps (asLByteString undefined)         describe "Text" $ chunkProps (asLText undefined)@@ -321,9 +346,11 @@         describe "LText" $ stripSuffixProps (undefined :: LText)         describe "ByteString" $ stripSuffixProps (undefined :: ByteString)         describe "LByteString" $ stripSuffixProps (undefined :: LByteString)+        describe "Seq" $ stripSuffixProps (undefined :: Seq Int)     describe "replicateM" $ do         describe "list" $ replicateMProps (undefined :: [Int])         describe "Vector" $ replicateMProps (undefined :: Vector Int)+        describe "Seq" $ replicateMProps (undefined :: Seq Int)     describe "encode/decode UTF8" $ do         describe "Text" $ utf8Props (undefined :: Text)         describe "LText" $ utf8Props (undefined :: LText)@@ -331,6 +358,14 @@         describe "list" $ compareLengthProps (undefined :: [Int])         describe "Text" $ compareLengthProps (undefined :: Text)         describe "LText" $ compareLengthProps (undefined :: LText)+    describe "Prefix" $ do+        describe "list" $ prefixProps (undefined :: [Int])+        describe "Text" $ prefixProps (undefined :: Text)+        describe "LText" $ prefixProps (undefined :: LText)+        describe "ByteString" $ prefixProps (undefined :: ByteString)+        describe "LByteString" $ prefixProps (undefined :: LByteString)+        describe "Vector" $ prefixProps (undefined :: Vector Int)+        describe "Seq" $ prefixProps (undefined :: Seq Int)  instance Arbitrary (Map Int Char) where     arbitrary = fromList <$> arbitrary@@ -349,4 +384,6 @@ instance Arbitrary Text where     arbitrary = fromList <$> arbitrary instance Arbitrary LText where+    arbitrary = fromList <$> arbitrary+instance Arbitrary (Seq Int) where     arbitrary = fromList <$> arbitrary