classy-prelude 0.1.0.0 → 0.2.0.0
raw patch · 16 files changed
+494/−254 lines, 16 filesdep +QuickCheckdep +basic-preludedep +classy-preludedep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: QuickCheck, basic-prelude, classy-prelude, hspec
Dependency ranges changed: base
API changes (from Hackage documentation)
- ClassyPrelude: ($) :: (a -> b) -> a -> b
- ClassyPrelude: (&&&) :: Arrow a => forall b c c'. a b c -> a b c' -> a b (c, c')
- ClassyPrelude: (&&) :: Bool -> Bool -> Bool
- ClassyPrelude: (*) :: Num a => a -> a -> a
- ClassyPrelude: (***) :: Arrow a => forall b c b' c'. a b c -> a b' c' -> a (b, b') (c, c')
- ClassyPrelude: (*>) :: Applicative f => f a -> f b -> f b
- ClassyPrelude: (+) :: Num a => a -> a -> a
- ClassyPrelude: (++) :: Monoid w => w -> w -> w
- ClassyPrelude: (-) :: Num a => a -> a -> a
- ClassyPrelude: (.) :: (b -> c) -> (a -> b) -> a -> c
- ClassyPrelude: (/) :: Fractional a => a -> a -> a
- ClassyPrelude: (/=) :: Eq a => a -> a -> Bool
- ClassyPrelude: (<$) :: Functor f => a -> f b -> f a
- ClassyPrelude: (<$>) :: Functor f => (a -> b) -> f a -> f b
- ClassyPrelude: (<) :: Ord a => a -> a -> Bool
- ClassyPrelude: (<*) :: Applicative f => f a -> f b -> f a
- ClassyPrelude: (<*>) :: Applicative f => f (a -> b) -> f a -> f b
- ClassyPrelude: (<.>) :: FilePath -> Text -> FilePath
- ClassyPrelude: (</>) :: FilePath -> FilePath -> FilePath
- ClassyPrelude: (<=) :: Ord a => a -> a -> Bool
- ClassyPrelude: (=<<) :: Monad m => (a -> m b) -> m a -> m b
- ClassyPrelude: (==) :: Eq a => a -> a -> Bool
- ClassyPrelude: (>) :: Ord a => a -> a -> Bool
- ClassyPrelude: (>=) :: Ord a => a -> a -> Bool
- ClassyPrelude: (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
- ClassyPrelude: (>>) :: Monad m => m a -> m b -> m b
- ClassyPrelude: (>>=) :: Monad m => m a -> (a -> m b) -> m b
- ClassyPrelude: (||) :: Bool -> Bool -> Bool
- ClassyPrelude: EQ :: Ordering
- ClassyPrelude: False :: Bool
- ClassyPrelude: GT :: Ordering
- ClassyPrelude: Just :: a -> Maybe a
- ClassyPrelude: LT :: Ordering
- ClassyPrelude: Left :: a -> Either a b
- ClassyPrelude: Nothing :: Maybe a
- ClassyPrelude: Right :: b -> Either a b
- ClassyPrelude: True :: Bool
- ClassyPrelude: basename :: FilePath -> FilePath
- ClassyPrelude: catMaybes :: [Maybe a] -> [a]
- ClassyPrelude: class Functor f => Applicative (f :: * -> *)
- ClassyPrelude: class Enum a
- ClassyPrelude: class Eq a
- ClassyPrelude: class (Typeable e, Show e) => Exception e
- ClassyPrelude: class Functor (f :: * -> *)
- ClassyPrelude: class (Real a, Enum a) => Integral a
- ClassyPrelude: class Monad (m :: * -> *)
- ClassyPrelude: class Monad m => MonadIO (m :: * -> *)
- ClassyPrelude: class Monoid a
- ClassyPrelude: class Eq a => Ord a
- ClassyPrelude: class Show a
- ClassyPrelude: compare :: Ord a => a -> a -> Ordering
- ClassyPrelude: concat :: Monoid w => [w] -> w
- ClassyPrelude: const :: a -> b -> a
- ClassyPrelude: data Bool :: *
- ClassyPrelude: data ByteString :: *
- ClassyPrelude: data Char :: *
- ClassyPrelude: data Either a b :: * -> * -> *
- ClassyPrelude: data FilePath :: *
- ClassyPrelude: data HashMap k v :: * -> * -> *
- ClassyPrelude: data HashSet a :: * -> *
- ClassyPrelude: data IO a :: * -> *
- ClassyPrelude: data Int :: *
- ClassyPrelude: data Int64 :: *
- ClassyPrelude: data Map k a :: * -> * -> *
- ClassyPrelude: data Maybe a :: * -> *
- ClassyPrelude: data Ordering :: *
- ClassyPrelude: data Set a :: * -> *
- ClassyPrelude: data SomeException :: *
- ClassyPrelude: data Text :: *
- ClassyPrelude: data Vector a :: * -> *
- ClassyPrelude: data Word :: *
- ClassyPrelude: data Word64 :: *
- ClassyPrelude: data Word8 :: *
- ClassyPrelude: div :: Integral a => a -> a -> a
- ClassyPrelude: divMod :: Integral a => a -> a -> (a, a)
- ClassyPrelude: either :: (a -> c) -> (b -> c) -> Either a b -> c
- ClassyPrelude: elem :: Eq a => a -> [a] -> Bool
- ClassyPrelude: empty :: CanEmpty c => c
- ClassyPrelude: enumFrom :: Enum a => a -> [a]
- ClassyPrelude: enumFromThen :: Enum a => a -> a -> [a]
- ClassyPrelude: enumFromThenTo :: Enum a => a -> a -> a -> [a]
- ClassyPrelude: enumFromTo :: Enum a => a -> a -> [a]
- ClassyPrelude: error :: [Char] -> a
- ClassyPrelude: even :: Integral a => a -> Bool
- ClassyPrelude: fail :: Monad m => String -> m a
- ClassyPrelude: filename :: FilePath -> FilePath
- ClassyPrelude: first :: Arrow a => forall b c d. a b c -> a (b, d) (c, d)
- ClassyPrelude: flip :: (a -> b -> c) -> b -> a -> c
- ClassyPrelude: fmap :: Functor f => (a -> b) -> f a -> f b
- ClassyPrelude: fromEnum :: Enum a => a -> Int
- ClassyPrelude: fromException :: Exception e => SomeException -> Maybe e
- ClassyPrelude: fromMaybe :: a -> Maybe a -> a
- ClassyPrelude: fst :: (a, b) -> a
- ClassyPrelude: hasExtension :: FilePath -> Text -> Bool
- ClassyPrelude: id :: a -> a
- ClassyPrelude: lift :: MonadTrans t => forall (m :: * -> *) a. Monad m => m a -> t m a
- ClassyPrelude: liftIO :: MonadIO m => forall a. IO a -> m a
- ClassyPrelude: mapMaybe :: (a -> Maybe b) -> [a] -> [b]
- ClassyPrelude: mappend :: Monoid a => a -> a -> a
- ClassyPrelude: max :: Ord a => a -> a -> a
- ClassyPrelude: maybe :: b -> (a -> b) -> Maybe a -> b
- ClassyPrelude: mconcat :: Monoid a => [a] -> a
- ClassyPrelude: mempty :: Monoid a => a
- ClassyPrelude: min :: Ord a => a -> a -> a
- ClassyPrelude: mod :: Integral a => a -> a -> a
- ClassyPrelude: not :: Bool -> Bool
- ClassyPrelude: odd :: Integral a => a -> Bool
- ClassyPrelude: or :: [Bool] -> Bool
- ClassyPrelude: otherwise :: Bool
- ClassyPrelude: partitionEithers :: [Either a b] -> ([a], [b])
- ClassyPrelude: pred :: Enum a => a -> a
- ClassyPrelude: print :: Show a => a -> IO ()
- ClassyPrelude: pure :: Applicative f => a -> f a
- ClassyPrelude: putStrLn :: Text -> IO ()
- ClassyPrelude: quot :: Integral a => a -> a -> a
- ClassyPrelude: quotRem :: Integral a => a -> a -> (a, a)
- ClassyPrelude: rem :: Integral a => a -> a -> a
- ClassyPrelude: return :: Monad m => a -> m a
- ClassyPrelude: second :: Arrow a => forall b c d. a b c -> a (d, b) (d, c)
- ClassyPrelude: snd :: (a, b) -> b
- ClassyPrelude: succ :: Enum a => a -> a
- ClassyPrelude: throwIO :: Exception e => e -> IO a
- ClassyPrelude: toEnum :: Enum a => Int -> a
- ClassyPrelude: toException :: Exception e => e -> SomeException
- ClassyPrelude: toInteger :: Integral a => a -> Integer
- ClassyPrelude: type LByteString = ByteString
- ClassyPrelude: type LHashMap = HashMap
- ClassyPrelude: type LText = Text
- ClassyPrelude: uncurry :: (a -> b -> c) -> (a, b) -> c
- ClassyPrelude: unzip :: [(a, b)] -> ([a], [b])
- ClassyPrelude: zip :: [a] -> [b] -> [(a, b)]
- ClassyPrelude: zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
- ClassyPrelude.Classes: class CanEmpty c
- ClassyPrelude.Classes: empty :: CanEmpty c => c
- ClassyPrelude.Classes: instance (accum ~ accum', CanFoldFunc c accum a) => CanFold accum a (c -> accum')
- ClassyPrelude.Classes: instance (b ~ c, CanFilterFunc b a) => CanFilter (b -> c) a
- ClassyPrelude.Classes: instance CanMapMFunc ci co i o m => CanMapM (ci -> m co) i o m
- ClassyPrelude.Classes: instance CanMapM_Func ci i o m => CanMapM_ (ci -> m ()) i o m
+ ClassyPrelude: drop :: CanSplitAt c i => i -> c -> c
+ ClassyPrelude: isInfixOf :: CanIsInfixOf a => a -> a -> Bool
+ ClassyPrelude: isPrefixOf :: CanStripPrefix a => a -> a -> Bool
+ ClassyPrelude: isSuffixOf :: CanStripSuffix a => a -> a -> Bool
+ ClassyPrelude: lines :: CanWords t => t -> [t]
+ ClassyPrelude: readMay :: (Read b, CanPack a Char) => a -> Maybe b
+ ClassyPrelude: repack :: (CanPack a i, CanPack b i) => a -> b
+ ClassyPrelude: reverse :: CanReverse a => a -> a
+ ClassyPrelude: split :: CanSplit c i => (i -> Bool) -> c -> [c]
+ ClassyPrelude: stripSuffix :: CanStripSuffix a => a -> a -> Maybe a
+ ClassyPrelude: take :: CanSplitAt c i => i -> c -> c
+ ClassyPrelude: unlines :: CanWords t => [t] -> t
+ ClassyPrelude: unwords :: CanWords t => [t] -> t
+ ClassyPrelude: words :: CanWords t => t -> [t]
+ ClassyPrelude.Classes: class CanIsInfixOf a
+ ClassyPrelude.Classes: class CanReplicate a i len | a -> i len
+ ClassyPrelude.Classes: class CanReverse a
+ ClassyPrelude.Classes: class CanSplit c i | c -> i
+ ClassyPrelude.Classes: class CanStripSuffix a
+ ClassyPrelude.Classes: class CanWords t
+ ClassyPrelude.Classes: drop :: CanSplitAt c i => i -> c -> c
+ ClassyPrelude.Classes: instance (CanFoldFunc c i accum, accum ~ result) => CanFold (c -> result) i accum
+ ClassyPrelude.Classes: instance (Monad m, CanMapM_Func ci i, r ~ m ()) => CanMapM_ (ci -> r) m i
+ ClassyPrelude.Classes: instance CanFilterFunc ci co i => CanFilter (ci -> co) i
+ ClassyPrelude.Classes: instance CanMapMFunc ci mco m i o => CanMapM (ci -> mco) m i o
+ ClassyPrelude.Classes: isInfixOf :: CanIsInfixOf a => a -> a -> Bool
+ ClassyPrelude.Classes: isPrefixOf :: CanStripPrefix a => a -> a -> Bool
+ ClassyPrelude.Classes: isSuffixOf :: CanStripSuffix a => a -> a -> Bool
+ ClassyPrelude.Classes: lines :: CanWords t => t -> [t]
+ ClassyPrelude.Classes: replicate :: CanReplicate a i len => len -> i -> a
+ ClassyPrelude.Classes: reverse :: CanReverse a => a -> a
+ ClassyPrelude.Classes: split :: CanSplit c i => (i -> Bool) -> c -> [c]
+ ClassyPrelude.Classes: stripSuffix :: CanStripSuffix a => a -> a -> Maybe a
+ ClassyPrelude.Classes: take :: CanSplitAt c i => i -> c -> c
+ ClassyPrelude.Classes: unlines :: CanWords t => [t] -> t
+ ClassyPrelude.Classes: unwords :: CanWords t => [t] -> t
+ ClassyPrelude.Classes: words :: CanWords t => t -> [t]
- ClassyPrelude: filter :: CanFilter f a => (a -> Bool) -> f
+ ClassyPrelude: filter :: CanFilter f i => (i -> Bool) -> f
- ClassyPrelude: fold :: CanFold accum a f => (accum -> a -> accum) -> accum -> f
+ ClassyPrelude: fold :: CanFold f i accum => (accum -> i -> accum) -> accum -> f
- ClassyPrelude: length :: CanLength c i => c -> i
+ ClassyPrelude: length :: CanLength c len => c -> len
- ClassyPrelude: mapM :: CanMapM f i o m => (i -> m o) -> f
+ ClassyPrelude: mapM :: CanMapM f m i o => (i -> m o) -> f
- ClassyPrelude: mapM_ :: CanMapM_ f i o m => (i -> m o) -> f
+ ClassyPrelude: mapM_ :: CanMapM_ f m i => (i -> m o) -> f
- ClassyPrelude.Classes: class CanConcatMapFunc ci co i o
+ ClassyPrelude.Classes: class CanConcatMapFunc ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci
- ClassyPrelude.Classes: class CanFilter f a
+ ClassyPrelude.Classes: class CanFilter f i
- ClassyPrelude.Classes: class CanFilterFunc c i | c -> i
+ ClassyPrelude.Classes: class CanFilterFunc ci co i | ci -> i co
- ClassyPrelude.Classes: class CanFold accum a f
+ ClassyPrelude.Classes: class CanFold f i accum
- ClassyPrelude.Classes: class CanFoldFunc c accum a | c -> a
+ ClassyPrelude.Classes: class CanFoldFunc c i accum | c -> i
- ClassyPrelude.Classes: class CanLength c i | c -> i
+ ClassyPrelude.Classes: class CanLength c len | c -> len
- ClassyPrelude.Classes: class CanMapFunc ci co i o
+ ClassyPrelude.Classes: class CanMapFunc ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci
- ClassyPrelude.Classes: class CanMapM f i o m
+ ClassyPrelude.Classes: class Monad m => CanMapM f m i o
- ClassyPrelude.Classes: class CanMapMFunc ci co i o m
+ ClassyPrelude.Classes: class Monad m => CanMapMFunc ci mco m i o | ci -> i, mco -> m o, ci o m -> mco, mco i -> ci
- ClassyPrelude.Classes: class CanMapM_ f i o m
+ ClassyPrelude.Classes: class Monad m => CanMapM_ f m i
- ClassyPrelude.Classes: class CanMapM_Func ci i o m
+ ClassyPrelude.Classes: class CanMapM_Func ci i | ci -> i
- ClassyPrelude.Classes: filter :: CanFilter f a => (a -> Bool) -> f
+ ClassyPrelude.Classes: filter :: CanFilter f i => (i -> Bool) -> f
- ClassyPrelude.Classes: filterFunc :: CanFilterFunc c i => (i -> Bool) -> c -> c
+ ClassyPrelude.Classes: filterFunc :: CanFilterFunc ci co i => (i -> Bool) -> ci -> co
- ClassyPrelude.Classes: fold :: CanFold accum a f => (accum -> a -> accum) -> accum -> f
+ ClassyPrelude.Classes: fold :: CanFold f i accum => (accum -> i -> accum) -> accum -> f
- ClassyPrelude.Classes: foldFunc :: CanFoldFunc c accum a => (accum -> a -> accum) -> accum -> c -> accum
+ ClassyPrelude.Classes: foldFunc :: CanFoldFunc c i accum => (accum -> i -> accum) -> accum -> c -> accum
- ClassyPrelude.Classes: length :: CanLength c i => c -> i
+ ClassyPrelude.Classes: length :: CanLength c len => c -> len
- ClassyPrelude.Classes: mapM :: CanMapM f i o m => (i -> m o) -> f
+ ClassyPrelude.Classes: mapM :: CanMapM f m i o => (i -> m o) -> f
- ClassyPrelude.Classes: mapMFunc :: CanMapMFunc ci co i o m => (i -> m o) -> ci -> m co
+ ClassyPrelude.Classes: mapMFunc :: CanMapMFunc ci mco m i o => (i -> m o) -> ci -> mco
- ClassyPrelude.Classes: mapM_ :: CanMapM_ f i o m => (i -> m o) -> f
+ ClassyPrelude.Classes: mapM_ :: CanMapM_ f m i => (i -> m o) -> f
- ClassyPrelude.Classes: mapM_Func :: CanMapM_Func ci i o m => (i -> m o) -> ci -> m ()
+ ClassyPrelude.Classes: mapM_Func :: (CanMapM_Func ci i, Monad m) => (i -> m o) -> ci -> m ()
Files
- ClassyPrelude.hs +42/−143
- ClassyPrelude/ByteString.hs +12/−5
- ClassyPrelude/Classes.hs +53/−25
- ClassyPrelude/FilePath.hs +4/−0
- ClassyPrelude/HashMap.hs +1/−3
- ClassyPrelude/HashSet.hs +3/−2
- ClassyPrelude/LByteString.hs +12/−5
- ClassyPrelude/LHashMap.hs +0/−38
- ClassyPrelude/LText.hs +32/−5
- ClassyPrelude/List.hs +22/−8
- ClassyPrelude/Map.hs +1/−3
- ClassyPrelude/Set.hs +3/−2
- ClassyPrelude/Text.hs +29/−5
- ClassyPrelude/Vector.hs +12/−8
- classy-prelude.cabal +17/−2
- test/main.hs +251/−0
ClassyPrelude.hs view
@@ -4,106 +4,8 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} module ClassyPrelude- ( -- * Standard- -- ** Operators- (Prelude.$)- , (Prelude.+)- , (Prelude.-)- , (Prelude.*)- , (Prelude./)- , (Prelude.&&)- , (Prelude.||)- , (Prelude..)- -- ** Functions- , Prelude.not- , Prelude.otherwise- , Prelude.fst- , Prelude.snd- , Prelude.id- , Prelude.maybe- , Prelude.either- , Prelude.flip- , Prelude.const- , Prelude.error- , Prelude.zip- , Prelude.unzip- , Prelude.zipWith- , Prelude.or- , Data.Text.IO.putStrLn- , Prelude.elem- , Prelude.odd- , Prelude.even- , Prelude.uncurry- -- ** Type classes- , Prelude.Ord (..)- , Prelude.Eq (..)- , Prelude.Enum (..)- , Prelude.Show- , Prelude.Functor (..)- , Prelude.Monad (..)- , (Control.Monad.=<<)- -- ** Data types- , Prelude.Maybe (..)- , Prelude.Ordering (..)- , Prelude.Bool (..)- , Prelude.Char- , Prelude.IO- , Prelude.Either (..)- , Prelude.Integral (..)- -- * Re-exports- -- ** Packed reps- , ByteString- , LByteString- , Text- , LText- -- ** Containers- , Map- , HashMap- , LHashMap- , Set- , HashSet- , Vector- -- ** Numbers- , Word8- , Word64- , Int64- , Prelude.Int- , Word- -- ** Monoids- , Monoid (..)- , concat- , (++)- -- ** Arrow- , Control.Arrow.first- , Control.Arrow.second- , (Control.Arrow.***)- , (Control.Arrow.&&&)- -- ** Maybe- , Data.Maybe.mapMaybe- , Data.Maybe.catMaybes- , Data.Maybe.fromMaybe- -- ** Either- , Data.Either.partitionEithers- -- ** Applicative- , Control.Applicative.Applicative (..)- , (Control.Applicative.<$>)- -- ** Monad- , (Control.Monad.>=>)- -- ** Transformers- , Control.Monad.Trans.Class.lift- , Control.Monad.IO.Class.MonadIO- , Control.Monad.IO.Class.liftIO- -- ** Exceptions- , Control.Exception.Exception (..)- , Control.Exception.SomeException- , Control.Exception.throwIO- -- ** Files- , F.FilePath- , (F.</>)- , (F.<.>)- , F.hasExtension- , F.basename- , F.filename+ ( -- * CorePrelude+ module CorePrelude -- * Non-standard -- ** List-like classes , map@@ -114,20 +16,31 @@ , null , pack , unpack+ , repack , fromList , toList , mapM , mapM_- , empty , stripPrefix+ , isPrefixOf+ , stripSuffix+ , isSuffixOf+ , isInfixOf , break , span , dropWhile , takeWhile , any , all- , splitAt+ , splitAt, take, drop , fold+ , words+ , unwords+ , lines+ , unlines+ , split+ , reverse+ , readMay -- ** Map-like , lookup , insert@@ -139,54 +52,28 @@ -- ** Files , readFile , writeFile- -- ** Print- , Prelude.print ) where import qualified Prelude-import Prelude (Char, (.))--import ClassyPrelude.Classes-import ClassyPrelude.List ()-import ClassyPrelude.ByteString-import ClassyPrelude.LByteString-import ClassyPrelude.Text-import ClassyPrelude.LText-import ClassyPrelude.Map-import ClassyPrelude.Set-import ClassyPrelude.FilePath ()-import ClassyPrelude.Vector-import ClassyPrelude.HashMap-import ClassyPrelude.LHashMap-import ClassyPrelude.HashSet--import Data.Monoid (Monoid (..))-import qualified Control.Arrow-import qualified Control.Applicative-import qualified Control.Monad-import qualified Control.Exception--import qualified Filesystem.Path.CurrentOS as F--import Data.Word (Word8, Word64, Word)-import Data.Int (Int64)--import qualified Data.Text.IO- import qualified Data.Maybe-import qualified Data.Either -import qualified Control.Monad.Trans.Class-import qualified Control.Monad.IO.Class--concat :: Monoid w => [w] -> w-concat = mconcat+import CorePrelude+import ClassyPrelude.Classes -infixr 5 ++-(++) :: Monoid w => w -> w -> w-(++) = mappend+import ClassyPrelude.ByteString ()+import ClassyPrelude.Classes ()+import ClassyPrelude.FilePath ()+import ClassyPrelude.HashMap ()+import ClassyPrelude.HashSet ()+import ClassyPrelude.LByteString ()+import ClassyPrelude.LText ()+import ClassyPrelude.List ()+import ClassyPrelude.Map ()+import ClassyPrelude.Set ()+import ClassyPrelude.Text ()+import ClassyPrelude.Vector () -show :: (Prelude.Show a, CanPack c Prelude.Char) => a -> c+show :: (Prelude.Show a, CanPack c Char) => a -> c show = pack . Prelude.show fromList :: CanPack c i => [i] -> c@@ -199,3 +86,15 @@ instance CanPack (Prelude.Maybe a) a where pack = Data.Maybe.listToMaybe unpack = Data.Maybe.maybeToList++readMay :: (Prelude.Read b, CanPack a Char) => a -> Maybe b+readMay a =+ case [x | (x, t) <- Prelude.reads (unpack a), null t] of+ [x] -> Just x+ _ -> Nothing++-- | Repack from one type to another, dropping to a list in the middle.+--+-- @repack = pack . unpack@.+repack :: (CanPack a i, CanPack b i) => a -> b+repack = pack . unpack
ClassyPrelude/ByteString.hs view
@@ -15,11 +15,11 @@ import qualified Filesystem.Path.CurrentOS as F import Data.Word (Word8) -instance (co ~ ByteString, i ~ Word8, o ~ Word8) => CanMapFunc ByteString co i o where+instance CanMapFunc ByteString ByteString Word8 Word8 where mapFunc = S.map-instance (co ~ ByteString, i ~ Word8, o ~ ByteString) => CanConcatMapFunc ByteString co i o where+instance CanConcatMapFunc ByteString ByteString Word8 ByteString where concatMapFunc = S.concatMap-instance CanFilterFunc ByteString Word8 where+instance CanFilterFunc ByteString ByteString Word8 where filterFunc = S.filter instance CanLength ByteString Prelude.Int where length = S.length@@ -30,8 +30,6 @@ instance CanPack ByteString Word8 where pack = S.pack unpack = S.unpack-instance CanEmpty ByteString where- empty = S.empty instance MonadIO m => CanReadFile (m ByteString) where readFile = liftIO . S.readFile . F.encodeString instance CanWriteFileFunc ByteString where@@ -46,3 +44,12 @@ all = S.all instance CanSplitAt ByteString Prelude.Int where splitAt = S.splitAt++instance CanReverse ByteString where+ reverse = S.reverse++instance CanFoldFunc ByteString Word8 accum where+ foldFunc = S.foldl'++instance CanReplicate ByteString Word8 Prelude.Int where+ replicate = S.replicate
ClassyPrelude/Classes.hs view
@@ -1,36 +1,38 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} module ClassyPrelude.Classes where import qualified Prelude+import Prelude (Monad) import qualified Filesystem.Path.CurrentOS as F import Control.Monad.IO.Class (MonadIO) class CanMap f i o where map :: (i -> o) -> f-class CanMapFunc ci co i o where+class CanMapFunc ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci where mapFunc :: (i -> o) -> ci -> co instance CanMapFunc ci co i o => CanMap (ci -> co) i o where map = mapFunc class CanConcatMap f i o where concatMap :: (i -> o) -> f-class CanConcatMapFunc ci co i o where+class CanConcatMapFunc ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci where concatMapFunc :: (i -> o) -> ci -> co instance CanConcatMapFunc ci co i o => CanConcatMap (ci -> co) i o where concatMap = concatMapFunc -class CanFilter f a where- filter :: (a -> Prelude.Bool) -> f-class CanFilterFunc c i | c -> i where- filterFunc :: (i -> Prelude.Bool) -> c -> c-instance (b ~ c, CanFilterFunc b a) => CanFilter (b -> c) a where+class CanFilter f i where+ 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 filter = filterFunc -class CanLength c i | c -> i where- length :: c -> i+class CanLength c len | c -> len where+ length :: c -> len class CanSingleton c i | c -> i where singleton :: i -> c@@ -42,26 +44,23 @@ pack :: [i] -> c unpack :: c -> [i] -class CanMapM f i o m where+class Monad m => CanMapM f m i o where mapM :: (i -> m o) -> f-class CanMapMFunc ci co i o m where- mapMFunc :: (i -> m o) -> ci -> m co-instance CanMapMFunc ci co i o m => CanMapM (ci -> m co) i o m where+class Monad m => CanMapMFunc ci mco m i o | ci -> i, mco -> m o, ci o m -> mco, mco i -> ci where+ mapMFunc :: (i -> m o) -> ci -> mco+instance CanMapMFunc ci mco m i o => CanMapM (ci -> mco) m i o where mapM = mapMFunc -class CanMapM_ f i o m where+class Monad m => CanMapM_ f m i where mapM_ :: (i -> m o) -> f-class CanMapM_Func ci i o m where- mapM_Func :: (i -> m o) -> ci -> m ()-instance CanMapM_Func ci i o m => CanMapM_ (ci -> m ()) i o m where+class CanMapM_Func ci i | ci -> i where+ mapM_Func :: Monad m => (i -> m o) -> ci -> m ()+instance (Monad m, CanMapM_Func ci i, r ~ m ()) => CanMapM_ (ci -> r) m i where mapM_ = mapM_Func class CanLookup c k v | c -> k v where lookup :: k -> c -> Prelude.Maybe v -class CanEmpty c where- empty :: c- class CanInsert f where insert :: f class CanInsertVal c k v | c -> k v where@@ -87,6 +86,7 @@ class CanStripPrefix a where stripPrefix :: a -> a -> Prelude.Maybe a+ isPrefixOf :: a -> a -> Prelude.Bool class CanBreak c i | c -> i where break :: (i -> Prelude.Bool) -> c -> (c, c)@@ -101,10 +101,38 @@ class CanSplitAt c i | c -> i where splitAt :: i -> c -> (c, c) -class CanFold accum a f where+take :: CanSplitAt c i => i -> c -> c+take i c = Prelude.fst (splitAt i c)+drop :: CanSplitAt c i => i -> c -> c+drop i c = Prelude.snd (splitAt i c)++class CanFold f i accum where -- | Strict left fold.- fold :: (accum -> a -> accum) -> accum -> f-class CanFoldFunc c accum a | c -> a where- foldFunc :: (accum -> a -> accum) -> accum -> c -> accum-instance (accum ~ accum', CanFoldFunc c accum a) => CanFold accum a (c -> accum') where+ fold :: (accum -> i -> accum) -> accum -> f+class CanFoldFunc c i accum | c -> i where+ -- | Strict left fold.+ foldFunc :: (accum -> i -> accum) -> accum -> c -> accum+instance (CanFoldFunc c i accum, accum ~ result) => CanFold (c -> result) i accum where fold = foldFunc++class CanWords t where+ words :: t -> [t]+ unwords :: [t] -> t+ lines :: t -> [t]+ unlines :: [t] -> t++class CanSplit c i | c -> i where+ split :: (i -> Prelude.Bool) -> c -> [c]++class CanStripSuffix a where+ stripSuffix :: a -> a -> Prelude.Maybe a+ isSuffixOf :: a -> a -> Prelude.Bool++class CanIsInfixOf a where+ isInfixOf :: a -> a -> Prelude.Bool++class CanReverse a where+ reverse :: a -> a++class CanReplicate a i len | a -> i len where+ replicate :: len -> i -> a
ClassyPrelude/FilePath.hs view
@@ -14,3 +14,7 @@ unpack = F.encodeString instance CanStripPrefix F.FilePath where stripPrefix = F.stripPrefix+ isPrefixOf a b =+ case stripPrefix a b of+ Prelude.Nothing -> Prelude.False+ Prelude.Just{} -> Prelude.True
ClassyPrelude/HashMap.hs view
@@ -17,7 +17,7 @@ instance CanMapFunc (Map k v1) (Map k v2) v1 v2 where mapFunc = Map.map-instance Hashable k => CanFilterFunc (Map k v) (k, v) where+instance Hashable k => CanFilterFunc (Map k v) (Map k v) (k, v) where filterFunc = Map.filterWithKey . Prelude.curry instance CanLength (Map k v) Prelude.Int where length = Map.size@@ -30,8 +30,6 @@ unpack = Map.toList instance (Prelude.Eq k, Hashable k) => CanLookup (Map k v) k v where lookup = Map.lookup-instance CanEmpty (Map k v) where- empty = Map.empty instance (Prelude.Eq k, Hashable k) => CanInsertVal (Map k v) k v where insertVal = Map.insert instance (Prelude.Eq k, Hashable k) => CanDelete (Map k v) k where
ClassyPrelude/HashSet.hs view
@@ -26,9 +26,10 @@ instance (Hashable x, Eq x) => CanPack (Set x) x where pack = Set.fromList unpack = Set.toList-instance CanEmpty (Set x) where- empty = Set.empty instance (Eq x, Hashable x, Set x ~ s, x ~ x') => CanInsert (x' -> s -> Set x) where insert = Set.insert instance (Eq x, Hashable x) => CanMember (Set x) x where member = Set.member++instance CanFoldFunc (Set a) a accum where+ foldFunc = Set.foldl'
ClassyPrelude/LByteString.hs view
@@ -17,11 +17,11 @@ type LByteString = L.ByteString -instance (co ~ LByteString, i ~ Word8, o ~ Word8) => CanMapFunc LByteString co i o where+instance CanMapFunc LByteString LByteString Word8 Word8 where mapFunc = L.map-instance (co ~ LByteString, i ~ Word8, o ~ LByteString) => CanConcatMapFunc LByteString co i o where+instance CanConcatMapFunc LByteString LByteString Word8 LByteString where concatMapFunc = L.concatMap-instance CanFilterFunc LByteString Word8 where+instance CanFilterFunc LByteString LByteString Word8 where filterFunc = L.filter instance CanLength LByteString Int64 where length = L.length@@ -32,8 +32,6 @@ instance CanPack LByteString Word8 where pack = L.pack unpack = L.unpack-instance CanEmpty LByteString where- empty = L.empty instance MonadIO m => CanReadFile (m LByteString) where readFile = liftIO . L.readFile . F.encodeString instance CanWriteFileFunc LByteString where@@ -48,3 +46,12 @@ all = L.all instance CanSplitAt LByteString Int64 where splitAt = L.splitAt++instance CanReverse LByteString where+ reverse = L.reverse++instance CanFoldFunc LByteString Word8 accum where+ foldFunc = L.foldl'++instance CanReplicate LByteString Word8 Int64 where+ replicate = L.replicate
− ClassyPrelude/LHashMap.hs
@@ -1,38 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.LHashMap- ( LHashMap- ) where--import qualified Prelude-import Prelude ((.), Char)-import ClassyPrelude.Classes-import qualified Data.HashMap.Lazy as Map-import Data.Hashable (Hashable)--type LHashMap = Map.HashMap-type Map = LHashMap--instance CanMapFunc (Map k v1) (Map k v2) v1 v2 where- mapFunc = Map.map-instance Hashable k => CanFilterFunc (Map k v) (k, v) where- filterFunc = Map.filterWithKey . Prelude.curry-instance CanLength (Map k v) Prelude.Int where- length = Map.size-instance (Prelude.Eq k, Hashable k, v' ~ v) => CanSingleton (v' -> Map k v) k where- singleton = Map.singleton-instance CanNull (Map k v) where- null = Map.null-instance (Prelude.Eq k, Hashable k) => CanPack (Map k v) (k, v) where- pack = Map.fromList- unpack = Map.toList-instance (Prelude.Eq k, Hashable k) => CanLookup (Map k v) k v where- lookup = Map.lookup-instance CanEmpty (Map k v) where- empty = Map.empty-instance (Prelude.Eq k, Hashable k) => CanInsertVal (Map k v) k v where- insertVal = Map.insert-instance (Prelude.Eq k, Hashable k) => CanDelete (Map k v) k where- delete = Map.delete
ClassyPrelude/LText.hs view
@@ -14,11 +14,11 @@ type LText = TL.Text -instance (co ~ LText, i ~ Char, o ~ Char) => CanMapFunc LText co i o where+instance CanMapFunc LText LText Char Char where mapFunc = TL.map-instance (co ~ LText, i ~ Char, o ~ LText) => CanConcatMapFunc LText co i o where+instance CanConcatMapFunc LText LText Char LText where concatMapFunc = TL.concatMap-instance CanFilterFunc LText Char where+instance CanFilterFunc LText LText Char where filterFunc = TL.filter instance CanSingleton LText Prelude.Char where singleton = TL.singleton@@ -27,10 +27,9 @@ instance CanPack LText Prelude.Char where pack = TL.pack unpack = TL.unpack-instance CanEmpty LText where- empty = TL.empty instance CanStripPrefix LText where stripPrefix = TL.stripPrefix+ isPrefixOf = TL.isPrefixOf instance CanBreak LText Prelude.Char where break = TL.break span = TL.span@@ -41,3 +40,31 @@ all = TL.all instance CanSplitAt LText Int64 where splitAt = TL.splitAt++instance CanWords LText where+ words = TL.words+ unwords = TL.unwords+ lines = TL.lines+ unlines = TL.unlines++instance CanSplit LText Char where+ split = TL.split++instance CanStripSuffix LText where+ stripSuffix = TL.stripSuffix+ isSuffixOf = TL.isSuffixOf++instance CanIsInfixOf LText where+ isInfixOf = TL.isInfixOf++instance CanReverse LText where+ reverse = TL.reverse++instance CanLength LText Int64 where+ length = TL.length++instance CanFoldFunc LText Char accum where+ foldFunc = TL.foldl'++instance CanReplicate LText LText Int64 where+ replicate = TL.replicate
ClassyPrelude/List.hs view
@@ -9,11 +9,11 @@ import ClassyPrelude.Classes import qualified Data.List -instance (i ~ a, co ~ [b]) => CanMapFunc [a] co i b where+instance CanMapFunc [a] [b] a b where mapFunc = Prelude.map-instance (i ~ a, co ~ [b]) => CanConcatMapFunc [a] co i [b] where+instance CanConcatMapFunc [a] [b] a [b] where concatMapFunc = Prelude.concatMap-instance CanFilterFunc [a] a where+instance CanFilterFunc [a] [a] a where filterFunc = Prelude.filter instance CanLength [a] Prelude.Int where length = Prelude.length@@ -24,14 +24,12 @@ instance CanPack [a] a where pack = Prelude.id unpack = Prelude.id-instance Prelude.Monad m => CanMapMFunc [a] [b] a b m where+instance Prelude.Monad m => CanMapMFunc [i] (m [o]) m i o where mapMFunc = Prelude.mapM-instance Prelude.Monad m => CanMapM_Func [a] a b m where+instance CanMapM_Func [a] a where mapM_Func = Prelude.mapM_ instance Prelude.Eq k => CanLookup [(k, v)] k v where lookup = Prelude.lookup-instance CanEmpty [a] where- empty = [] instance Prelude.Eq k => CanInsertVal [(k, v)] k v where insertVal k v c = (k, v) : delete k c instance Prelude.Eq k => CanDelete [(k, v)] k where@@ -40,6 +38,7 @@ member x = Prelude.any (Prelude.== x) instance Prelude.Eq a => CanStripPrefix [a] where stripPrefix = Data.List.stripPrefix+ isPrefixOf = Data.List.isPrefixOf instance CanBreak [a] a where break = Prelude.break span = Prelude.span@@ -50,5 +49,20 @@ all = Prelude.all instance CanSplitAt [c] Prelude.Int where splitAt = Prelude.splitAt-instance CanFoldFunc [a] accum a where+instance CanFoldFunc [a] a accum where foldFunc = Data.List.foldl'++instance (c ~ Prelude.Char) => CanWords [c] where+ words = Prelude.words+ unwords = Prelude.unwords+ lines = Prelude.lines+ unlines = Prelude.unlines++instance Prelude.Eq a => CanIsInfixOf [a] where+ isInfixOf = Data.List.isInfixOf++instance CanReverse [a] where+ reverse = Prelude.reverse++instance CanReplicate [i] i Prelude.Int where+ replicate = Prelude.replicate
ClassyPrelude/Map.hs view
@@ -14,7 +14,7 @@ instance CanMapFunc (Map k v1) (Map k v2) v1 v2 where mapFunc = Map.map-instance Prelude.Ord k => CanFilterFunc (Map k v) (k, v) where+instance Prelude.Ord k => CanFilterFunc (Map k v) (Map k v) (k, v) where filterFunc = Map.filterWithKey . Prelude.curry instance CanLength (Map k v) Prelude.Int where length = Map.size@@ -27,8 +27,6 @@ unpack = Map.toList instance Prelude.Ord k => CanLookup (Map k v) k v where lookup = Map.lookup-instance CanEmpty (Map k v) where- empty = Map.empty instance Prelude.Ord k => CanInsertVal (Map k v) k v where insertVal = Map.insert instance Prelude.Ord k => CanDelete (Map k v) k where
ClassyPrelude/Set.hs view
@@ -23,9 +23,10 @@ instance Prelude.Ord x => CanPack (Set x) x where pack = Set.fromList unpack = Set.toList-instance CanEmpty (Set x) where- empty = Set.empty instance (Prelude.Ord x, Set x ~ s, x ~ x') => CanInsert (x' -> s -> Set x) where insert = Set.insert instance Prelude.Ord x => CanMember (Set x) x where member = Set.member++instance CanFoldFunc (Set a) a accum where+ foldFunc = Set.foldl'
ClassyPrelude/Text.hs view
@@ -12,11 +12,11 @@ import Data.Text (Text) import qualified Data.Text as T -instance (co ~ Text, i ~ Char, o ~ Char) => CanMapFunc Text co i o where+instance CanMapFunc Text Text Char Char where mapFunc = T.map-instance (co ~ Text, i ~ Char, o ~ Text) => CanConcatMapFunc Text co i o where+instance CanConcatMapFunc Text Text Char Text where concatMapFunc = T.concatMap-instance CanFilterFunc Text Char where+instance CanFilterFunc Text Text Char where filterFunc = T.filter instance CanLength Text Prelude.Int where length = T.length@@ -27,10 +27,9 @@ instance CanPack Text Prelude.Char where pack = T.pack unpack = T.unpack-instance CanEmpty Text where- empty = T.empty instance CanStripPrefix Text where stripPrefix = T.stripPrefix+ isPrefixOf = T.isPrefixOf instance CanBreak Text Prelude.Char where break = T.break span = T.span@@ -41,3 +40,28 @@ all = T.all instance CanSplitAt Text Prelude.Int where splitAt = T.splitAt++instance CanWords Text where+ words = T.words+ unwords = T.unwords+ lines = T.lines+ unlines = T.unlines++instance CanSplit Text Char where+ split = T.split++instance CanStripSuffix Text where+ stripSuffix = T.stripSuffix+ isSuffixOf = T.isSuffixOf++instance CanIsInfixOf Text where+ isInfixOf = T.isInfixOf++instance CanReverse Text where+ reverse = T.reverse++instance CanFoldFunc Text Char accum where+ foldFunc = T.foldl'++instance CanReplicate Text Text Prelude.Int where+ replicate = T.replicate
ClassyPrelude/Vector.hs view
@@ -12,11 +12,11 @@ import Data.Vector (Vector) import qualified Data.Vector as V -instance (i ~ a, co ~ Vector b) => CanMapFunc (Vector a) co i b where+instance CanMapFunc (Vector a) (Vector b) a b where mapFunc = V.map-instance (i ~ a, co ~ Vector b) => CanConcatMapFunc (Vector a) co i (Vector b) where+instance CanConcatMapFunc (Vector a) (Vector b) a (Vector b) where concatMapFunc = V.concatMap-instance CanFilterFunc (Vector a) a where+instance CanFilterFunc (Vector a) (Vector a) a where filterFunc = V.filter instance CanLength (Vector a) Prelude.Int where length = V.length@@ -27,12 +27,10 @@ instance CanPack (Vector a) a where pack = V.fromList unpack = V.toList-instance Prelude.Monad m => CanMapMFunc (Vector a) (Vector b) a b m where+instance Prelude.Monad m => CanMapMFunc (Vector i) (m (Vector o)) m i o where mapMFunc = V.mapM-instance Prelude.Monad m => CanMapM_Func (Vector a) a b m where+instance CanMapM_Func (Vector a) a where mapM_Func = V.mapM_-instance CanEmpty (Vector a) where- empty = V.empty instance Prelude.Eq x => CanMember (Vector x) x where member x = V.any (Prelude.== x) instance CanBreak (Vector a) a where@@ -45,5 +43,11 @@ all = V.all instance CanSplitAt (Vector a) Prelude.Int where splitAt = V.splitAt-instance CanFoldFunc (Vector a) accum a where+instance CanFoldFunc (Vector a) a accum where foldFunc = V.foldl'++instance CanReverse (Vector a) where+ reverse = V.reverse++instance CanReplicate (Vector a) a Prelude.Int where+ replicate = V.replicate
classy-prelude.cabal view
@@ -1,5 +1,5 @@ name: classy-prelude-version: 0.1.0.0+version: 0.2.0.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@@ -24,9 +24,9 @@ ClassyPrelude.FilePath ClassyPrelude.Vector ClassyPrelude.HashMap- ClassyPrelude.LHashMap ClassyPrelude.HashSet build-depends: base >= 4 && < 5+ , basic-prelude >= 0.2 && < 0.3 , system-filepath >= 0.4 && < 0.5 , transformers , containers@@ -36,3 +36,18 @@ , unordered-containers , hashable ghc-options: -Wall -fno-warn-orphans++test-suite test+ hs-source-dirs: test+ main-is: main.hs+ type: exitcode-stdio-1.0+ build-depends: classy-prelude+ , base+ , hspec == 1.3.*+ , QuickCheck+ , transformers+ ghc-options: -Wall++source-repository head+ type: git+ location: git://github.com/snoyberg/classy-prelude.git
+ test/main.hs view
@@ -0,0 +1,251 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+import Test.Hspec+import Test.Hspec.QuickCheck+import ClassyPrelude+import ClassyPrelude.Classes+import Test.QuickCheck.Arbitrary+import Prelude (asTypeOf, undefined, fromIntegral)+import qualified Prelude+import Control.Monad.Trans.Writer (tell, Writer, runWriter)++dictionaryProps+ :: ( CanInsertVal a Int Char+ , CanDelete a Int+ , Show a+ , Eq a+ , Arbitrary a+ , Monoid a+ , CanLookup a Int Char+ )+ => a -> Spec+dictionaryProps dummy = do+ prop "insert x y (insert x z c) == insert x y c" $ \x y z c ->+ insert x y (insert x z (c `asTypeOf` dummy)) == insert x y c+ prop "insert x y (delete x c) == insert x y c" $ \x y c ->+ insert x y (delete x (c `asTypeOf` dummy)) == insert x y c+ prop "delete x (insert x y c) == delete x c" $ \x y c ->+ delete x (insert x y (c `asTypeOf` dummy)) == delete x c+ prop "lookup k (insert k v empty) == Just v" $ \k v ->+ lookup k (insert k v empty `asTypeOf` dummy) == Just v+ prop "lookup k (delete k c) == Nothing" $ \k c ->+ lookup k (delete k c`asTypeOf` dummy) == Nothing++mapProps :: ( CanPack a i+ , CanPack b j+ , Eq a+ , Eq c+ , Show a+ , Arbitrary a+ , Eq b+ , Show b+ , Arbitrary b+ , CanMapFunc a b i j+ , CanMapFunc a c i k+ , CanMapFunc b c j k+ )+ => a+ -> (i -> j)+ -> (j -> k)+ -> Spec+mapProps dummy f g = do+ prop "map f c == pack (map f (unpack c))" $ \c ->+ map f (c `asTypeOf` dummy) == pack (map f (unpack c))+ prop "map (f . g) c == map f (map g c)" $ \c ->+ map (g . f) (c `asTypeOf` dummy) == map g (map f c)++concatMapProps :: ( CanPack a i+ , CanPack b j+ , CanPack js j+ , Eq a+ , Show a+ , Arbitrary a+ , Eq b+ , Show b+ , Arbitrary b+ , CanMapFunc a b i j+ , CanConcatMapFunc a b i js+ )+ => a+ -> (i -> js)+ -> Spec+concatMapProps dummy f = do+ prop "concatMap f c == pack (concatMap (unpack . f) (unpack c))" $ \c ->+ concatMap f (c `asTypeOf` dummy) == pack (concatMap (unpack . f) (unpack c))++filterProps :: ( CanPack a i+ , Show a+ , Arbitrary a+ , Eq a+ , CanFilterFunc a a i+ )+ => a+ -> (i -> Bool)+ -> Spec+filterProps dummy f = do+ prop "filter f c == pack (filter f (unpack c))" $ \c ->+ filter f (c `asTypeOf` dummy) == pack (filter f (unpack c))++lengthProps :: ( Show a+ , Eq a+ , Arbitrary a+ , CanPack a i+ , CanLength a len+ , Prelude.Num len+ , Eq len+ , CanNull a+ , Ord len+ , Monoid a+ )+ => a -> Spec+lengthProps dummy = do+ prop "length c == fromIntegral (length (unpack c))" $ \c ->+ length (c `asTypeOf` dummy) == fromIntegral (length (unpack c))+ prop "null c == (length c == 0)" $ \c ->+ null (c `asTypeOf` dummy) == (length c == 0)+ prop "length (x ++ y) <= length x + length y" $ \x y ->+ length (x ++ y `asTypeOf` dummy) <= length x + length y+ prop "length (x ++ y) >= max (length x) (length y)" $ \x y ->+ length (x ++ y `asTypeOf` dummy) >= max (length x) (length y)+ prop "length (x ++ empty) == length x" $ \x ->+ length (x ++ empty `asTypeOf` dummy) == length x+ prop "null empty" $ null (empty `asTypeOf` dummy)++{-+mapMProps :: ( Show a+ , Arbitrary a+ , CanPack a i+ , Eq i+ , CanMapMFunc a co i i+ , CanPack co i+ , Eq co+ )+ => a -> Spec+-}+mapMProps dummy = do+ let f :: Int -> Writer [Int] Int+ f x = tell [x] >> return x+ prop "mapM_ f c == mapM_ f (toList c)" $ \c ->+ runWriter (mapM f (c `asTypeOf` dummy)) ==+ let (x, y) = runWriter (mapM f (toList c))+ in (pack x, y)++mapM_Props :: ( Show a+ , Arbitrary a+ , CanPack a i+ , Eq i+ , CanMapM_Func a i+ )+ => a -> Spec+mapM_Props dummy = do+ let f x = tell [x]+ prop "mapM_ f c == mapM_ f (toList c)" $ \c ->+ runWriter (mapM_ f (c `asTypeOf` dummy)) == runWriter (mapM_ f (toList c))++foldProps dummy f accum =+ prop "fold f accum c == fold f accum (toList c)" $ \c ->+ fold f accum (c `asTypeOf` dummy) == fold f accum (toList c)++replicateProps :: ( Show a+ , Eq a+ , CanReplicate a i len+ , Integral len+ , Show len+ , Arbitrary len+ , Show i+ , Arbitrary i+ )+ => a -> ([i] -> a) -> Spec+replicateProps dummy pack' =+ prop "replicate i a == pack (replicate i a)" $ \{- takes too long i-} a ->+ (replicate i a `asTypeOf` dummy) == pack' (replicate (fromIntegral i) a)+ where+ i = 3++main :: IO ()+main = hspec $ do+ describe "dictionary" $ do+ describe "Data.Map" $ dictionaryProps (undefined :: Map Int Char)+ describe "Data.HashMap" $ dictionaryProps (undefined :: HashMap Int Char)+ describe "assoc list" $ dictionaryProps (undefined :: [(Int, Char)])+ describe "map" $ do+ describe "list" $ mapProps (undefined :: [Int]) (+ 1) (+ 2)+ describe "Data.Vector" $ mapProps (undefined :: Vector Int) (+ 1) (+ 2)+ describe "Data.Set" $ mapProps (undefined :: Set Int) (+ 1) (+ 2)+ describe "Data.HashSet" $ mapProps (undefined :: HashSet Int) (+ 1) (+ 2)+ describe "Data.ByteString" $ mapProps (undefined :: ByteString) (+ 1) (+ 2)+ 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 "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])+ describe "Data.ByteString" $ concatMapProps (undefined :: ByteString) (\i -> fromList [i + 1, i + 2])+ 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 "filter" $ do+ describe "list" $ filterProps (undefined :: [Int]) (< 20)+ describe "Data.Vector" $ filterProps (undefined :: Vector Int) (< 20)+ describe "Data.ByteString" $ filterProps (undefined :: ByteString) (< 20)+ describe "Data.ByteString.Lazy" $ filterProps (undefined :: LByteString) (< 20)+ describe "Data.Text" $ filterProps (undefined :: Text) (< 'A')+ 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 "length" $ do+ describe "list" $ lengthProps (undefined :: [Int])+ describe "Data.Vector" $ lengthProps (undefined :: Vector Int)+ describe "Data.ByteString" $ lengthProps (undefined :: ByteString)+ describe "Data.ByteString.Lazy" $ lengthProps (undefined :: LByteString)+ describe "Data.Text" $ lengthProps (undefined :: Text)+ describe "Data.Text.Lazy" $ lengthProps (undefined :: LText)+ describe "Data.Map" $ lengthProps (undefined :: Map Int Char)+ describe "Data.HashMap" $ lengthProps (undefined :: HashMap Int Char)+ describe "Data.Set" $ lengthProps (undefined :: Set Int)+ describe "Data.HashSet" $ lengthProps (undefined :: HashSet Int)+ describe "mapM" $ do+ describe "list" $ mapMProps (undefined :: [Int])+ describe "Data.Vector" $ mapMProps (undefined :: Vector Int)+ describe "mapM_" $ do+ describe "list" $ mapM_Props (undefined :: [Int])+ describe "Data.Vector" $ mapM_Props (undefined :: Vector Int)+ describe "fold" $ do+ let f = flip (:)+ describe "list" $ foldProps (undefined :: [Int]) f []+ describe "Data.Vector" $ foldProps (undefined :: Vector Int) f []+ describe "Data.ByteString" $ foldProps (undefined :: ByteString) f []+ describe "Data.ByteString.Lazy" $ foldProps (undefined :: LByteString) f []+ describe "Data.Text" $ foldProps (undefined :: Text) f []+ 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 "replicate" $ do+ describe "list" $ replicateProps (undefined :: [Int]) pack+ describe "Data.Vector" $ replicateProps (undefined :: Vector Int) pack+ describe "Data.ByteString" $ replicateProps (undefined :: ByteString) pack+ describe "Data.ByteString.Lazy" $ replicateProps (undefined :: LByteString) pack+ describe "Data.Text" $ replicateProps (undefined :: Text) concat+ describe "Data.Text.Lazy" $ replicateProps (undefined :: LText) concat++instance Arbitrary (Map Int Char) where+ arbitrary = fromList <$> arbitrary+instance Arbitrary (HashMap Int Char) where+ arbitrary = fromList <$> arbitrary+instance Arbitrary (Vector Int) where+ arbitrary = fromList <$> arbitrary+instance Arbitrary (Set Int) where+ arbitrary = fromList <$> arbitrary+instance Arbitrary (HashSet Int) where+ arbitrary = fromList <$> arbitrary+instance Arbitrary ByteString where+ arbitrary = fromList <$> arbitrary+instance Arbitrary LByteString where+ arbitrary = fromList <$> arbitrary+instance Arbitrary Text where+ arbitrary = fromList <$> arbitrary+instance Arbitrary LText where+ arbitrary = fromList <$> arbitrary