packages feed

classy-prelude 0.3.1 → 0.4.0

raw patch · 10 files changed

+173/−6 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- ClassyPrelude.Classes: instance CanFilterFunc ci co i => CanFilter (ci -> co) i
+ ClassyPrelude: decodeUtf8 :: CanDecodeUtf8 f => f
+ ClassyPrelude: encodeUtf8 :: CanEncodeUtf8 f => f
+ ClassyPrelude: forM :: CanMapMFunc ci mco m i o => ci -> (i -> m o) -> mco
+ ClassyPrelude: forM_ :: (Monad m, CanMapM_Func ci i) => ci -> (i -> m o) -> m ()
+ ClassyPrelude: replicateM :: (CanReplicateM c i len, Monad m) => len -> m i -> m c
+ ClassyPrelude.Classes: class CanDecodeUtf8 f
+ ClassyPrelude.Classes: class CanDecodeUtf8Func ci co | co -> ci, ci -> co
+ ClassyPrelude.Classes: class CanEncodeUtf8 f
+ ClassyPrelude.Classes: class CanEncodeUtf8Func ci co | co -> ci, ci -> co
+ ClassyPrelude.Classes: class CanFilterM f m i
+ ClassyPrelude.Classes: class CanFilterMFunc c i | c -> i
+ ClassyPrelude.Classes: class CanLines f
+ ClassyPrelude.Classes: class CanLinesFunc t
+ ClassyPrelude.Classes: class CanReplicateM c i len | c -> i len
+ ClassyPrelude.Classes: class CanUnlines t
+ ClassyPrelude.Classes: decodeUtf8 :: CanDecodeUtf8 f => f
+ ClassyPrelude.Classes: decodeUtf8Func :: CanDecodeUtf8Func ci co => ci -> co
+ ClassyPrelude.Classes: encodeUtf8 :: CanEncodeUtf8 f => f
+ ClassyPrelude.Classes: encodeUtf8Func :: CanEncodeUtf8Func ci co => ci -> co
+ ClassyPrelude.Classes: filterM :: CanFilterM f m i => (i -> m Bool) -> f
+ ClassyPrelude.Classes: filterMFunc :: (CanFilterMFunc c i, Monad m) => (i -> m Bool) -> c -> m c
+ ClassyPrelude.Classes: instance (CanFilterFunc ci co i, ci ~ co) => CanFilter (ci -> co) i
+ ClassyPrelude.Classes: instance (CanFilterMFunc ci i, m ci ~ mco, Monad m) => CanFilterM (ci -> mco) m i
+ ClassyPrelude.Classes: instance (CanLinesFunc t, out ~ [t]) => CanLines (t -> out)
+ ClassyPrelude.Classes: instance CanDecodeUtf8Func ci co => CanDecodeUtf8 (ci -> co)
+ ClassyPrelude.Classes: instance CanEncodeUtf8Func ci co => CanEncodeUtf8 (ci -> co)
+ ClassyPrelude.Classes: linesFunc :: CanLinesFunc t => t -> [t]
+ ClassyPrelude.Classes: replicateM :: (CanReplicateM c i len, Monad m) => len -> m i -> m c
- ClassyPrelude: lines :: CanWords t => t -> [t]
+ ClassyPrelude: lines :: CanLines f => f
- ClassyPrelude: unlines :: CanWords t => [t] -> t
+ ClassyPrelude: unlines :: CanUnlines t => [t] -> t
- ClassyPrelude.Classes: lines :: CanWords t => t -> [t]
+ ClassyPrelude.Classes: lines :: CanLines f => f
- ClassyPrelude.Classes: unlines :: CanWords t => [t] -> t
+ ClassyPrelude.Classes: unlines :: CanUnlines t => [t] -> t

Files

ClassyPrelude.hs view
@@ -12,6 +12,8 @@     , empty     , append     , (++)+      -- ** Monad+    , module Control.Monad       -- * Non-standard       -- ** List-like classes     , map@@ -27,6 +29,9 @@     , toList     , mapM     , mapM_+    , forM+    , forM_+    , replicateM     , stripPrefix     , isPrefixOf     , stripSuffix@@ -48,6 +53,8 @@     , reverse     , readMay     , replicate+    , encodeUtf8+    , decodeUtf8       -- ** Map-like     , lookup     , insert@@ -77,6 +84,7 @@  import qualified Prelude import qualified Data.Maybe+import Control.Monad (when, unless, void, liftM, ap, forever)  import CorePrelude import ClassyPrelude.Classes@@ -166,3 +174,9 @@  asVector :: Vector a -> Vector a asVector = id++forM :: CanMapMFunc ci mco m i o => ci -> (i -> m o) -> mco+forM = flip mapM++forM_ :: (Monad m, CanMapM_Func ci i) => ci -> (i -> m o) -> m ()+forM_ = flip mapM_
ClassyPrelude/ByteString.hs view
@@ -53,3 +53,9 @@  instance CanReplicate ByteString Word8 Prelude.Int where     replicate = S.replicate++instance CanStripSuffix ByteString where+    stripSuffix x y+        | x `S.isSuffixOf` y = Prelude.Just (S.take (S.length y Prelude.- S.length x) y)+        | Prelude.otherwise = Prelude.Nothing+    isSuffixOf = S.isSuffixOf
ClassyPrelude/Classes.hs view
@@ -28,9 +28,16 @@     filter :: (i -> Prelude.Bool) -> f class CanFilterFunc ci co i | ci -> i co where     filterFunc :: (i -> Prelude.Bool) -> ci -> co-instance (CanFilterFunc ci co i) => CanFilter (ci -> co) i where+instance (CanFilterFunc ci co i, ci ~ co) => CanFilter (ci -> co) i where     filter = filterFunc +class CanFilterM f m i where+    filterM :: (i -> m Prelude.Bool) -> f+class CanFilterMFunc c i | c -> i where+    filterMFunc :: Monad m => (i -> m Prelude.Bool) -> c -> m c+instance (CanFilterMFunc ci i, m ci ~ mco, Monad m) => CanFilterM (ci -> mco) m i where+    filterM = filterMFunc+ class CanLength c len | c -> len where     length :: c -> len @@ -58,6 +65,9 @@ instance (Monad m, CanMapM_Func ci i, r ~ m ()) => CanMapM_ (ci -> r) m i where     mapM_ = mapM_Func +class CanReplicateM c i len | c -> i len where+    replicateM :: Monad m => len -> m i -> m c+ class CanLookup c k v | c -> k v where     lookup :: k -> c -> Prelude.Maybe v @@ -118,7 +128,15 @@ class CanWords t where     words :: t -> [t]     unwords :: [t] -> t-    lines :: t -> [t]++class CanLines f where+    lines :: f+class CanLinesFunc t where+    linesFunc :: t -> [t]+instance (CanLinesFunc t, out ~ [t]) => CanLines (t -> out) where+    lines = linesFunc++class CanUnlines t where     unlines :: [t] -> t  class CanSplit c i | c -> i where@@ -140,3 +158,20 @@ class CanToChunks c i | c -> i, i -> c where     toChunks :: c -> [i]     fromChunks :: [i] -> c++class CanEncodeUtf8 f where+    encodeUtf8 :: f+class CanEncodeUtf8Func ci co | co -> ci, ci -> co where+    encodeUtf8Func :: ci -> co+instance CanEncodeUtf8Func ci co => CanEncodeUtf8 (ci -> co) where+    encodeUtf8 = encodeUtf8Func++class CanDecodeUtf8 f where+    decodeUtf8 :: f+-- | Note: implementations should ensure that @decodeUtf8Func@ is a total+-- function. As such, the standard @decodeUtf8@ provided by the text package+-- should not be used, but instead @decodeUtf8With lenientDecode@.+class CanDecodeUtf8Func ci co | co -> ci, ci -> co where+    decodeUtf8Func :: ci -> co+instance CanDecodeUtf8Func ci co => CanDecodeUtf8 (ci -> co) where+    decodeUtf8 = decodeUtf8Func
ClassyPrelude/LByteString.hs view
@@ -60,3 +60,9 @@ instance CanToChunks LByteString Data.ByteString.ByteString where     toChunks = L.toChunks     fromChunks = L.fromChunks++instance CanStripSuffix LByteString where+    stripSuffix x y+        | x `L.isSuffixOf` y = Prelude.Just (L.take (L.length y Prelude.- L.length x) y)+        | Prelude.otherwise = Prelude.Nothing+    isSuffixOf = L.isSuffixOf
ClassyPrelude/LText.hs view
@@ -12,6 +12,9 @@ import qualified Data.Text.Lazy as TL import Data.Int (Int64) import qualified Data.Text+import qualified Data.Text.Lazy.Encoding+import qualified Data.Text.Encoding.Error+import Data.ByteString.Lazy (ByteString)  type LText = TL.Text @@ -45,7 +48,11 @@ instance CanWords LText where     words = TL.words     unwords = TL.unwords-    lines = TL.lines++instance CanLinesFunc LText where+    linesFunc = TL.lines++instance CanUnlines LText where     unlines = TL.unlines  instance CanSplit LText Char where@@ -73,3 +80,8 @@ instance CanToChunks LText Data.Text.Text where     toChunks = TL.toChunks     fromChunks = TL.fromChunks++instance CanEncodeUtf8Func LText ByteString where+    encodeUtf8Func = Data.Text.Lazy.Encoding.encodeUtf8+instance CanDecodeUtf8Func ByteString LText where+    decodeUtf8Func = Data.Text.Lazy.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
ClassyPrelude/List.hs view
@@ -8,6 +8,7 @@ import Prelude ((.)) import ClassyPrelude.Classes import qualified Data.List+import qualified Control.Monad  instance CanMapFunc [a] [b] a b where     mapFunc = Prelude.map@@ -15,6 +16,8 @@     concatMapFunc = Prelude.concatMap instance CanFilterFunc [a] [a] a where     filterFunc = Prelude.filter+instance CanFilterMFunc [a] a where+    filterMFunc = Control.Monad.filterM instance CanLength [a] Prelude.Int where     length = Prelude.length instance CanSingleton [a] a where@@ -55,7 +58,11 @@ instance (c ~ Prelude.Char) => CanWords [c] where     words = Prelude.words     unwords = Prelude.unwords-    lines = Prelude.lines++instance (c ~ Prelude.Char) => CanLinesFunc [c] where+    linesFunc = Prelude.lines++instance (c ~ Prelude.Char) => CanUnlines [c] where     unlines = Prelude.unlines  instance Prelude.Eq a => CanIsInfixOf [a] where@@ -66,3 +73,6 @@  instance CanReplicate [i] i Prelude.Int where     replicate = Prelude.replicate++instance CanReplicateM [a] a Prelude.Int where+    replicateM = Control.Monad.replicateM
ClassyPrelude/Text.hs view
@@ -11,6 +11,9 @@ import ClassyPrelude.Classes import Data.Text (Text) import qualified Data.Text as T+import qualified Data.Text.Encoding+import qualified Data.Text.Encoding.Error+import Data.ByteString (ByteString)  instance CanMapFunc Text Text Char Char where     mapFunc = T.map@@ -44,7 +47,11 @@ instance CanWords Text where     words = T.words     unwords = T.unwords-    lines = T.lines++instance CanLinesFunc Text where+    linesFunc = T.lines++instance CanUnlines Text where     unlines = T.unlines  instance CanSplit Text Char where@@ -65,3 +72,8 @@  instance CanReplicate Text Text Prelude.Int where     replicate = T.replicate++instance CanEncodeUtf8Func Text ByteString where+    encodeUtf8Func = Data.Text.Encoding.encodeUtf8+instance CanDecodeUtf8Func ByteString Text where+    decodeUtf8Func = Data.Text.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
ClassyPrelude/Vector.hs view
@@ -18,6 +18,8 @@     concatMapFunc = V.concatMap instance CanFilterFunc (Vector a) (Vector a) a where     filterFunc = V.filter+instance CanFilterMFunc (Vector a) a where+    filterMFunc = V.filterM instance CanLength (Vector a) Prelude.Int where     length = V.length instance CanSingleton (Vector a) a where@@ -51,3 +53,6 @@  instance CanReplicate (Vector a) a Prelude.Int where     replicate = V.replicate++instance CanReplicateM (Vector a) a Prelude.Int where+    replicateM = V.replicateM
classy-prelude.cabal view
@@ -1,5 +1,5 @@ name:                classy-prelude-version:             0.3.1+version:             0.4.0 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
test/main.hs view
@@ -11,6 +11,8 @@ import Prelude (asTypeOf, undefined, fromIntegral) import qualified Prelude import Control.Monad.Trans.Writer (tell, Writer, runWriter)+import Data.Maybe (isJust)+import Data.Functor.Identity (runIdentity)  dictionaryProps     :: ( CanInsertVal a Int Char@@ -90,6 +92,21 @@     prop "filter f c == pack (filter f (unpack c))" $ \c ->         (repack (filter f (c `asTypeOf` dummy)) `asTypeOf` dummy) == pack (filter f (unpack c)) +filterMProps :: ( CanPack a i+                , Show a+                , Arbitrary a+                , Eq a+                , CanFilterMFunc a i+                )+             => a+             -> (i -> Bool)+             -> Spec+filterMProps dummy f' = do+    prop "filterM f c == fmap pack (filterM f (unpack c))" $ \c ->+        runIdentity (fmap repack (filterM f (c `asTypeOf` dummy))) `asTypeOf` dummy == runIdentity (fmap pack (filterM f (unpack c)))+  where+    f = return . f'+ lengthProps :: ( Show a                , Eq a                , Arbitrary a@@ -178,6 +195,42 @@     prop "fromChunks . return . concat . toChunks == id" $ \a ->         fromChunks [concat $ toChunks (a `asTypeOf` dummy)] == a +stripSuffixProps :: ( Eq a+                    , Monoid a+                    , CanStripSuffix a+                    , Show a+                    , Arbitrary a+                    ) => a -> Spec+stripSuffixProps dummy = do+    prop "stripSuffix y (x ++ y) == Just x" $ \x y ->+        stripSuffix y (x ++ y) == Just (x `asTypeOf` dummy)+    prop "isJust (stripSuffix x y) == isSuffixOf x y" $ \x y ->+        isJust (stripSuffix x y) == isSuffixOf x (y `asTypeOf` dummy)++replicateMProps :: ( Eq c+                   , Show len+                   , Arbitrary len+                   , CanReplicateM c i len+                   , CanReplicate c i len+                   , Show i+                   , Arbitrary i+                   , Integral len+                   ) => c -> Spec+replicateMProps dummy = do+    prop "runIdentity (replicateM i (return x)) == replicate i x" $ \i' x ->+        let i = i' `mod` 20+         in runIdentity (replicateM i (return x)) == (replicate i x `asTypeOf` dummy)++utf8Props :: ( Eq t+             , Show t+             , Arbitrary t+             , CanEncodeUtf8Func t b+             , CanDecodeUtf8Func b t+             ) => t -> Spec+utf8Props dummy = do+    prop "decodeUtf8 . encodeUtf8 == id" $ \t ->+        decodeUtf8 (encodeUtf8 t) == (t `asTypeOf` dummy)+ main :: IO () main = hspec $ do     describe "dictionary" $ do@@ -209,6 +262,9 @@         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 "filterM" $ do+        describe "list" $ filterMProps (undefined :: [Int]) (< 20)+        describe "Data.Vector" $ filterMProps (undefined :: Vector Int) (< 20)     describe "length" $ do         describe "list" $ lengthProps (undefined :: [Int])         describe "Data.Vector" $ lengthProps (undefined :: Vector Int)@@ -246,6 +302,17 @@     describe "chunks" $ do         describe "ByteString" $ chunkProps (asLByteString undefined)         describe "Text" $ chunkProps (asLText undefined)+    describe "stripSuffix" $ do+        describe "Text" $ stripSuffixProps (undefined :: Text)+        describe "LText" $ stripSuffixProps (undefined :: LText)+        describe "ByteString" $ stripSuffixProps (undefined :: ByteString)+        describe "LByteString" $ stripSuffixProps (undefined :: LByteString)+    describe "replicateM" $ do+        describe "list" $ replicateMProps (undefined :: [Int])+        describe "Vector" $ replicateMProps (undefined :: Vector Int)+    describe "encode/decode UTF8" $ do+        describe "Text" $ utf8Props (undefined :: Text)+        describe "LText" $ utf8Props (undefined :: LText)  instance Arbitrary (Map Int Char) where     arbitrary = fromList <$> arbitrary