classy-prelude 0.5.10 → 1.5.0.3
raw patch · 22 files changed
Files
- ChangeLog.md +132/−0
- ClassyPrelude.hs +0/−437
- ClassyPrelude/ByteString.hs +0/−111
- ClassyPrelude/Char.hs +0/−15
- ClassyPrelude/Classes.hs +0/−287
- ClassyPrelude/FilePath.hs +0/−27
- ClassyPrelude/HashMap.hs +0/−62
- ClassyPrelude/HashSet.hs +0/−53
- ClassyPrelude/LByteString.hs +0/−117
- ClassyPrelude/LText.hs +0/−141
- ClassyPrelude/List.hs +0/−224
- ClassyPrelude/Map.hs +0/−62
- ClassyPrelude/Maybe.hs +0/−63
- ClassyPrelude/Sequence.hs +0/−156
- ClassyPrelude/Set.hs +0/−69
- ClassyPrelude/Text.hs +0/−133
- ClassyPrelude/UVector.hs +0/−185
- ClassyPrelude/Vector.hs +0/−187
- README.md +57/−0
- classy-prelude.cabal +76/−57
- src/ClassyPrelude.hs +641/−0
- test/main.hs +199/−177
+ ChangeLog.md view
@@ -0,0 +1,132 @@+# ChangeLog for classy-prelude++## 1.5.0.3++* Don't import Data.Functor.unzip [#215](https://github.com/snoyberg/mono-traversable/pull/215)++## 1.5.0.2++* Fix building with time >= 1.10 [#207](https://github.com/snoyberg/mono-traversable/pull/207).++## 1.5.0.1++* Export a compatibility shim for `parseTime` as it has been removed in `time-1.10`.+ See <https://hackage.haskell.org/package/time-1.12/changelog>++## 1.5.0++* Removed `alwaysSTM` and `alwaysSucceedsSTM`. See+ <https://github.com/ghc-proposals/ghc-proposals/pull/77>++## 1.4.0++* Switch to `MonadUnliftIO`++## 1.3.1++* Add terminal IO functions++## 1.3.0++* Tracing functions leave warnings when used++## 1.2.0.1++* Use `HasCallStack` in `undefined`++## 1.2.0++* Don't generalize I/O functions to `IOData`, instead specialize to+ `ByteString`. See:+ http://www.snoyman.com/blog/2016/12/beware-of-readfile#real-world-failures++## 1.0.2++* Export `parseTimeM` for `time >= 1.5`++## 1.0.1++* Add the `say` package reexports+* Add the `stm-chans` package reexports++## 1.0.0.2++* Allow basic-prelude 0.6++## 1.0.0.1++* Support for safe-exceptions-0.1.4.0++## 1.0.0++* Support for mono-traversable-1.0.0+* Switch to safe-exceptions+* Add monad-unlift and lifted-async++## 0.12.8++* Add (<&&>),(<||>) [#125](https://github.com/snoyberg/classy-prelude/pull/125)++## 0.12.7++* Concurrency: reexport `Control.Concurrent.Lifted` and provide `yieldThread`++## 0.12.6++* Regeneralize intercalate [#119](https://github.com/snoyberg/classy-prelude/pull/119)+* Add missing exports for `traverse_` and `for_`+* Generalize `mapM_` and `forM_` for GHC 7.10++## 0.12.5.1++* Support for QuickCheck 2.8.2++## 0.12.5++* Expose `Alternative` and `optional`++## 0.12.4++* Expose `traverse_` and `for_`++## 0.12.3++* mono-traversable-0.9.3 support++## 0.12.2++add `errorM`, `terrorM`, and `terror`++## 0.12.0++* Drop system-filepath++## 0.11.1.1++* Compatibility with time >= 1.5 [#100](https://github.com/snoyberg/classy-prelude/pull/100)++## 0.11.1++* Fix deprecation warnings for `elem`++## 0.11.0++* Upgrade to mutable-containers 0.3+* Include dlist support++## 0.10.5++* Export `Data.Mutable`++## 0.10.4++* Expose all of Data.Functor++## 0.10.3++* Expose `liftA` functions and `<**>` [#94](https://github.com/snoyberg/classy-prelude/pull/94)++## 0.10.2++* Provide `foldMap` and `fold` as synonyms for `concatMap` and `concat`.+* Switch to more general `Traversable`-based functions (`sequence_` in particular).
− ClassyPrelude.hs
@@ -1,437 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude- ( -- * CorePrelude- module CorePrelude- , Seq- , undefined- -- * Standard- -- ** Monoid- , empty- , append- , (++)- -- ** Monad- , module Control.Monad- -- ** Mutable references- , module Control.Concurrent.MVar.Lifted- , module Data.IORef.Lifted- -- ** Debugging- , trace- , traceShow- , traceId- , traceM- , traceShowId- , traceShowM- -- * Non-standard- -- ** List-like classes- , map- , concat- , concatMap- , filter- , find- , length- , singleton- , null- , pack- , unpack- , repack- , fromList- , toList- , mapM- , mapM_- , forM- , forM_- , replicateM- , replicateM_- , stripPrefix- , isPrefixOf- , stripSuffix- , isSuffixOf- , isInfixOf- , break- , span- , dropWhile- , takeWhile- , any- , all- , splitAt, take, drop- , fold- , words- , unwords- , lines- , unlines- , split- , reverse- , readMay- , replicate- , intercalate- , intersperse- , encodeUtf8- , decodeUtf8- , subsequences- , permutations- , partition- , zip, zip3, zip4, zip5, zip6, zip7- , unzip, unzip3, unzip4, unzip5, unzip6, unzip7- , zipWith, zipWith3, zipWith4, zipWith5, zipWith6, zipWith7- , nub- , nubBy- , sort- , sortBy- , sortWith- , group- , group'- , groupBy- , groupBy'- , groupWith- , cons- , uncons- , compareLength- , Foldable.sum- , Foldable.product- , repeat- -- ** Map-like- , lookup- , insert- , delete- -- ** Set-like- , member- , notMember- , elem- , notElem- , union- , difference- , (\\)- , intersection- , intersect- , unions- -- ** Text-like- , show- , toLower- , toUpper- , toCaseFold- , toStrict- , fromStrict- -- ** IO- , readFile- , writeFile- , getLine- , print- -- ** Chunking- , toChunks- , fromChunks- -- ** Exceptions- , catchAny- , handleAny- , tryAny- , catchAnyDeep- , handleAnyDeep- , tryAnyDeep- , catchIO- , handleIO- , tryIO- -- ** Force types- -- | Helper functions for situations where type inferer gets confused.- , asByteString- , asLByteString- , asHashMap- , asHashSet- , asText- , asLText- , asList- , asMap- , asMaybe- , asSet- , asVector- , asUVector - , asIOException- , asSomeException- ) where--import qualified Prelude-import Control.Monad (when, unless, void, liftM, ap, forever, join, sequence, sequence_, replicateM_)-import Control.Monad.Trans.Control (MonadBaseControl, liftBaseWith, restoreM)-import Control.Concurrent.Async (withAsync, waitCatch)-import Control.Concurrent.MVar.Lifted-import Data.IORef.Lifted-import Data.Monoid (Monoid)-import qualified Data.Monoid as Monoid-import Data.Foldable (Foldable)-import qualified Data.Foldable as Foldable-import Control.DeepSeq (NFData, ($!!))--import CorePrelude hiding (print, undefined)-import ClassyPrelude.Classes--import ClassyPrelude.ByteString ()-import ClassyPrelude.Char ()-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.Maybe ()-import ClassyPrelude.Set ()-import ClassyPrelude.Text ()-import ClassyPrelude.Vector ()-import ClassyPrelude.UVector ()-import ClassyPrelude.Sequence (Seq)--import Debug.Trace (trace, traceShow)--show :: (Show a, CanPack c Char) => a -> c-show = pack . Prelude.show--fromList :: CanPack c i => [i] -> c-fromList = pack--toList :: CanPack c i => c -> [i]-toList = unpack--readMay :: (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--append :: Monoid m => m -> m -> m-append = mappend-{-# INLINE append #-}--infixr 5 ++-(++) :: Monoid m => m -> m -> m-(++) = mappend-{-# INLINE (++) #-}--infixl 9 \\{-This comment teaches CPP correct behaviour -}--- | An alias for `difference`.-(\\) :: CanDifference c => c -> c -> c-(\\) = difference-{-# INLINE (\\) #-}---- | An alias for `intersection`.-intersect :: CanIntersection c => c -> c -> c-intersect = intersection-{-# INLINE intersect #-}--unions :: (Foldable cc, Monoid c, CanUnion c) => cc c -> c-unions = Foldable.foldl' union Monoid.mempty--intercalate :: (CanConcat c i, CanIntersperse c i) => i -> c -> i-intercalate xs xss = concat (intersperse xs xss)--asByteString :: ByteString -> ByteString-asByteString = id--asLByteString :: LByteString -> LByteString-asLByteString = id--asHashMap :: HashMap k v -> HashMap k v-asHashMap = id--asHashSet :: HashSet a -> HashSet a-asHashSet = id--asText :: Text -> Text-asText = id--asLText :: LText -> LText-asLText = id--asList :: [a] -> [a]-asList = id--asMap :: Map k v -> Map k v-asMap = id--asMaybe :: Maybe a -> Maybe a-asMaybe = id--asSet :: Set a -> Set a-asSet = id--asVector :: Vector a -> Vector a-asVector = id--asUVector :: UVector a -> UVector a-asUVector = id--forM :: CanMapM ci mco m i o => ci -> (i -> m o) -> mco-forM = flip mapM--forM_ :: (Monad m, CanMapM_ ci i) => ci -> (i -> m o) -> m ()-forM_ = flip mapM_---- | An alias for 'member'-elem :: CanMember c k => k -> c -> Bool-elem = member---- | An alias for 'notMember'-notElem :: CanMember c k => k -> c -> Bool-notElem = notMember--print :: (Show a, MonadIO m) => a -> m ()-print = liftIO . Prelude.print--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)---- | Sort elements using the user supplied function to project something out of--- each element.--- 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)---- | We define our own @undefined@ which is marked as deprecated. This makes it--- useful to use during development, but let's you more easily getting--- notification if you accidentally ship partial code in production.------ The classy prelude recommendation for when you need to really have a partial--- function in production is to use @error@ with a very descriptive message so--- that, in case an exception is thrown, you get more information than--- @Prelude.undefined@.------ Since 0.5.5-undefined :: a-undefined = error "ClassyPrelude.undefined"-{-# DEPRECATED undefined "It is highly recommended that you either avoid partial functions or provide meaningful error messages" #-}---- | A version of 'catch' which is specialized for any exception. This--- simplifies usage as no explicit type signatures are necessary.------ Note that since version 0.5.9, this function now has proper support for--- asynchronous exceptions, by only catching exceptions generated by the--- internal action.------ Since 0.5.6-catchAny :: MonadBaseControl IO m => m a -> (SomeException -> m a) -> m a-catchAny action onE = tryAny action >>= either onE return---- | A version of 'handle' which is specialized for any exception. This--- simplifies usage as no explicit type signatures are necessary.------ Note that since version 0.5.9, this function now has proper support for--- asynchronous exceptions, by only catching exceptions generated by the--- internal action.------ Since 0.5.6-handleAny :: MonadBaseControl IO m => (SomeException -> m a) -> m a -> m a-handleAny = flip catchAny---- | A version of 'try' which is specialized for any exception.--- This simplifies usage as no explicit type signatures are necessary.------ Note that since version 0.5.9, this function now has proper support for--- asynchronous exceptions, by only catching exceptions generated by the--- internal action.------ Since 0.5.6-tryAny :: MonadBaseControl IO m => m a -> m (Either SomeException a)-tryAny m =- liftBaseWith (\runInIO -> withAsync (runInIO m) waitCatch) >>=- either (return . Left) (liftM Right . restoreM)---- | An extension to @catchAny@ which ensures that the return value is fully--- evaluated. See @tryAnyDeep@.------ Since 0.5.9-catchAnyDeep :: (NFData a, MonadBaseControl IO m) => m a -> (SomeException -> m a) -> m a-catchAnyDeep action onE = tryAnyDeep action >>= either onE return---- | @flip catchAnyDeep@------ Since 0.5.6-handleAnyDeep :: (NFData a, MonadBaseControl IO m) => (SomeException -> m a) -> m a -> m a-handleAnyDeep = flip catchAnyDeep---- | An extension to @tryAny@ which ensures that the return value is fully--- evaluated. In other words, if you get a @Right@ response here, you can be--- confident that using it will not result in another exception.------ Since 0.5.9-tryAnyDeep :: (NFData a, MonadBaseControl IO m)- => m a- -> m (Either SomeException a)-tryAnyDeep m = tryAny $ do- x <- m- return $!! x---- | A version of 'catch' which is specialized for IO exceptions. This--- simplifies usage as no explicit type signatures are necessary.------ Since 0.5.6-catchIO :: MonadBaseControl IO m => m a -> (IOException -> m a) -> m a-catchIO = catch---- | A version of 'handle' which is specialized for IO exceptions. This--- simplifies usage as no explicit type signatures are necessary.------ Since 0.5.6-handleIO :: MonadBaseControl IO m => (IOException -> m a) -> m a -> m a-handleIO = handle---- | A version of 'try' which is specialized for IO exceptions.--- This simplifies usage as no explicit type signatures are necessary.------ Since 0.5.6-tryIO :: MonadBaseControl IO m => m a -> m (Either IOException a)-tryIO = try---- |------ Since 0.5.6-asSomeException :: SomeException -> SomeException-asSomeException = id---- |------ Since 0.5.6-asIOException :: IOException -> IOException-asIOException = id---- |------ Since 0.5.9-traceId :: String -> String-traceId a = trace a a---- |------ Since 0.5.9-traceM :: (Monad m) => String -> m ()-traceM string = trace string $ return ()---- |------ Since 0.5.9-traceShowId :: (Show a) => a -> a-traceShowId a = trace (show a) a---- |------ Since 0.5.9-traceShowM :: (Show a, Monad m) => a -> m ()-traceShowM = traceM . show
− ClassyPrelude/ByteString.hs
@@ -1,111 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.ByteString- ( ByteString- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.ByteString as ByteString-import qualified Filesystem.Path.CurrentOS as FilePath---instance CanMap ByteString ByteString Word8 Word8 where- map = ByteString.map--instance CanConcatMap ByteString ByteString Word8 ByteString where- concatMap = ByteString.concatMap--instance CanFilter ByteString Word8 where- filter = ByteString.filter--instance CanLength ByteString Int where- length = ByteString.length--instance CanSingleton ByteString Word8 where- singleton = ByteString.singleton--instance CanNull ByteString where- null = ByteString.null--instance CanPack ByteString Word8 where- pack = ByteString.pack- unpack = ByteString.unpack--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--instance CanWriteFile ByteString where- writeFile fp = liftIO . ByteString.writeFile (FilePath.encodeString fp)--instance CanBreak ByteString Word8 where- break = ByteString.break- span = ByteString.span- dropWhile = ByteString.dropWhile- takeWhile = ByteString.takeWhile--instance CanAny ByteString Word8 where- any = ByteString.any- all = ByteString.all--instance CanSplitAt ByteString Int where- splitAt = ByteString.splitAt--instance CanReverse ByteString where- reverse = ByteString.reverse--instance CanFold ByteString Word8 accum where- fold = ByteString.foldl'--instance CanReplicate ByteString Word8 Int where- replicate = ByteString.replicate--instance CanStripSuffix ByteString where- stripSuffix x y- | x `ByteString.isSuffixOf` y = Just (ByteString.take (ByteString.length y - ByteString.length x) y)- | otherwise = Nothing- isSuffixOf = ByteString.isSuffixOf--instance CanIsInfixOf ByteString where- isInfixOf = ByteString.isInfixOf--instance MonadIO m => CanGetLine (m ByteString) where- getLine = liftIO ByteString.getLine--instance CanPartition ByteString Word8 where- partition = ByteString.partition--instance CanCons ByteString Word8 where- cons = ByteString.cons--instance CanUncons ByteString Word8 where- uncons = ByteString.uncons--instance CanGroupBy ByteString Word8 where- groupBy = ByteString.groupBy--instance CanGroup ByteString Word8 where- group = ByteString.group--instance CanZipWith ByteString Word8 ByteString Word8 [a] a where- zipWith = ByteString.zipWith--instance CanZip ByteString Word8 ByteString Word8 [] where- zip = ByteString.zip--instance CanUnzip ByteString Word8 ByteString Word8 [] where- unzip = ByteString.unzip--instance CanEmpty ByteString
− ClassyPrelude/Char.hs
@@ -1,15 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.Char where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.Char as Char--instance CanToLower Char where- toLower = Char.toLower--instance CanToUpper Char where- toUpper = Char.toUpper
− ClassyPrelude/Classes.hs
@@ -1,287 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DefaultSignatures #-}-module ClassyPrelude.Classes where--import CorePrelude-import qualified Data.List as List---class CanMap ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci where- map :: (i -> o) -> ci -> co--class CanConcatMap ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci where- concatMap :: (i -> o) -> ci -> co--class CanFilter c i | c -> i where- filter :: (i -> Bool) -> c -> c--class CanFilterM c i | c -> i where- filterM :: Monad m => (i -> m Bool) -> c -> m c--class CanLength c len | c -> len where- length :: c -> len--class CanSingleton c i | c -> i where- singleton :: i -> c--class CanNull c where- null :: c -> Bool--class CanPack c i | c -> i where- pack :: [i] -> c- unpack :: c -> [i]- subsequences :: c -> [c]- subsequences = List.map pack . List.subsequences . unpack- permutations :: c -> [c]- permutations = List.map pack . List.permutations . unpack--class CanIntersperse c i | c -> i where- intersperse :: i -> c -> c--class Monad m => CanMapM ci mco m i o | ci -> i, mco -> m o, ci o m -> mco, mco i -> ci where- mapM :: (i -> m o) -> ci -> mco--class CanMapM_ ci i | ci -> i where- mapM_ :: Monad m => (i -> m o) -> ci -> m ()--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 -> Maybe v--class CanInsert f where- insert :: f--class CanInsertVal c k v | c -> k v where- insertVal :: k -> v -> c -> c--instance (CanInsertVal c' k v, c ~ c') => CanInsert (k -> v -> c -> c') where- insert = insertVal--class CanDelete f where- delete :: f--class CanDeleteVal c k | c -> k where- deleteVal :: k -> c -> c--instance (CanDeleteVal c' k, c ~ c') => CanDelete (k -> c -> c') where- delete = deleteVal--class CanMember c k | c -> k where- member :: k -> c -> Bool- notMember :: k -> c -> Bool- notMember k = not . member k--class CanReadFile a where- readFile :: MonadIO m => FilePath -> m a--class CanWriteFile a where- writeFile :: MonadIO m => FilePath -> a -> m ()--class CanStripPrefix a where- stripPrefix :: a -> a -> Maybe a- isPrefixOf :: a -> a -> Bool--class CanBreak c i | c -> i where- break :: (i -> Bool) -> c -> (c, c)- span :: (i -> Bool) -> c -> (c, c)- dropWhile :: (i -> Bool) -> c -> c- takeWhile :: (i -> Bool) -> c -> c--class CanAny c i | c -> i where- any :: (i -> Bool) -> c -> Bool- all :: (i -> Bool) -> c -> Bool--class CanSplitAt c i | c -> i where- splitAt :: i -> c -> (c, c)--class CanFold c i accum | c -> i where- -- | Strict left fold.- fold :: (accum -> i -> accum) -> accum -> c -> accum--class CanWords t where- words :: t -> [t]- unwords :: [t] -> t--class CanLines t where- lines :: t -> [t]--class CanUnlines t where- unlines :: [t] -> t--class CanSplit c i | c -> i where- split :: (i -> Bool) -> c -> [c]--class CanStripSuffix a where- stripSuffix :: a -> a -> Maybe a- isSuffixOf :: a -> a -> Bool--class CanIsInfixOf a where- isInfixOf :: a -> a -> Bool--class CanReverse a where- reverse :: a -> a--class CanReplicate a i len | a -> i len where- replicate :: len -> i -> a--class CanToChunks c i | c -> i, i -> c where- toChunks :: c -> [i]- fromChunks :: [i] -> c--class CanEncodeUtf8 ci co | co -> ci, ci -> co where- encodeUtf8 :: ci -> co---- | Note: implementations should ensure that @decodeUtf8@ is a total--- function. As such, the standard @decodeUtf8@ provided by the text package--- should not be used, but instead @decodeUtf8With lenientDecode@.-class CanDecodeUtf8 ci co | co -> ci, ci -> co where- decodeUtf8 :: ci -> co--class CanToStrict a b where- toStrict :: a -> b- fromStrict :: b -> a--class CanGetLine a where- getLine :: a--class CanToLower a where- toLower :: a -> a--class CanToUpper a where- toUpper :: a -> a--class CanToCaseFold a where- toCaseFold :: a -> a--class CanFind c i | c -> i where- find :: (i -> Bool) -> c -> Maybe i--class CanConcat c i | c -> i where- concat :: c -> i--class CanPartition c i | c -> i where- partition :: (i -> Bool) -> c -> (c, c)--class CanNubBy c i | c -> i where- nubBy :: (i -> i -> Bool) -> c -> c-- nub :: (Ord i, CanNubBy c i) => c -> c- nub = nubBy (==)--class CanUnion c where- union :: c -> c -> c--class CanDifference c where- difference :: c -> c -> c--class CanIntersection c where- intersection :: c -> c -> c--class CanSortBy c a | c -> a where- sortBy :: (a -> a -> Ordering) -> c -> c--class Ord a => CanSort c a | c -> a where- sort :: c -> c- default sort :: CanSortBy c a => c -> c- sort = sortBy compare--class CanCons c a where- cons :: a -> c -> c--class CanUncons c a where- uncons :: c -> Maybe (a, c)--class CanCompareLength c where- -- | This is a more effective alternative to statements like @i >= length - -- xs@ for types having an O(n) complexity of `length` operation like list - -- 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 CanGroupBy' c a | c -> a where- -- | Similar to standard 'groupBy', but operates on the whole collection, - -- not just the consecutive items.- 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 CanGroup' c a | c -> a where- -- | Similar to standard 'group', but operates on the whole collection, - -- not just the consecutive items.- group' :: c -> [c]- default group' :: (CanGroupBy' c a, Eq a) => c -> [c]- group' = groupBy' (==)--class CanRepeat c a | c -> a where- repeat :: a -> c--class CanZipWith c1 i1 c2 i2 c3 i3 | c1 -> i1, c2 -> i2, c3 -> i3 where- zipWith :: (i1 -> i2 -> i3) -> c1 -> c2 -> c3--class CanZipWith3 c1 i1 c2 i2 c3 i3 c4 i4 | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4 where- zipWith3 :: (i1 -> i2 -> i3 -> i4) -> c1 -> c2 -> c3 -> c4--class CanZipWith4 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5 where- zipWith4 :: (i1 -> i2 -> i3 -> i4 -> i5) -> c1 -> c2 -> c3 -> c4 -> c5--class CanZipWith5 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 c6 i6 | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5, c6 -> i6 where- zipWith5 :: (i1 -> i2 -> i3 -> i4 -> i5 -> i6) -> c1 -> c2 -> c3 -> c4 -> c5 -> c6--class CanZipWith6 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 c6 i6 c7 i7 | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5, c6 -> i6, c7 -> i7 where- zipWith6 :: (i1 -> i2 -> i3 -> i4 -> i5 -> i6 -> i7) -> c1 -> c2 -> c3 -> c4 -> c5 -> c6 -> c7--class CanZipWith7 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 c6 i6 c7 i7 c8 i8 | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5, c6 -> i6, c7 -> i7, c8 -> i8 where- zipWith7 :: (i1 -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8) -> c1 -> c2 -> c3 -> c4 -> c5 -> c6 -> c7 -> c8--class CanZip c1 i1 c2 i2 t | c1 -> i1, c2 -> i2 where- zip :: c1 -> c2 -> t (i1, i2)--class CanZip3 c1 i1 c2 i2 c3 i3 t | c1 -> i1, c2 -> i2, c3 -> i3 where- zip3 :: c1 -> c2 -> c3 -> t (i1, i2, i3)--class CanZip4 c1 i1 c2 i2 c3 i3 c4 i4 t | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4 where- zip4 :: c1 -> c2 -> c3 -> c4 -> t (i1, i2, i3, i4)--class CanZip5 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 t | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5 where- zip5 :: c1 -> c2 -> c3 -> c4 -> c5 -> t (i1, i2, i3, i4, i5)--class CanZip6 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 c6 i6 t | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5, c6 -> i6 where- zip6 :: c1 -> c2 -> c3 -> c4 -> c5 -> c6 -> t (i1, i2, i3, i4, i5, i6)--class CanZip7 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 c6 i6 c7 i7 t | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5, c6 -> i6, c7 -> i7 where- zip7 :: c1 -> c2 -> c3 -> c4 -> c5 -> c6 -> c7 -> t (i1, i2, i3, i4, i5, i6, i7)--class CanUnzip c1 i1 c2 i2 t | c1 -> i1, c2 -> i2 where- unzip :: t (i1, i2) -> (c1, c2)--class CanUnzip3 c1 i1 c2 i2 c3 i3 t | c1 -> i1, c2 -> i2, c3 -> i3 where- unzip3 :: t (i1, i2, i3) -> (c1, c2, c3)--class CanUnzip4 c1 i1 c2 i2 c3 i3 c4 i4 t | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4 where- unzip4 :: t (i1, i2, i3, i4) -> (c1, c2, c3, c4)--class CanUnzip5 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 t | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5 where- unzip5 :: t (i1, i2, i3, i4, i5) -> (c1, c2, c3, c4, c5)--class CanUnzip6 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 c6 i6 t | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5, c6 -> i6 where- unzip6 :: t (i1, i2, i3, i4, i5, i6) -> (c1, c2, c3, c4, c5, c6)--class CanUnzip7 c1 i1 c2 i2 c3 i3 c4 i4 c5 i5 c6 i6 c7 i7 t | c1 -> i1, c2 -> i2, c3 -> i3, c4 -> i4, c5 -> i5, c6 -> i6, c7 -> i7 where- unzip7 :: t (i1, i2, i3, i4, i5, i6, i7) -> (c1, c2, c3, c4, c5, c6, c7)--class CanEmpty a where- empty :: a- default empty :: Monoid a => a- empty = mempty
− ClassyPrelude/FilePath.hs
@@ -1,27 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.FilePath () where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.List as List-import qualified Filesystem.Path.CurrentOS as FilePath---instance CanPack FilePath Char where- pack = FilePath.decodeString- unpack = FilePath.encodeString--instance CanIntersperse FilePath Char where- intersperse c = pack . List.intersperse c . unpack--instance CanStripPrefix FilePath where- stripPrefix = FilePath.stripPrefix- isPrefixOf a b =- case stripPrefix a b of- Nothing -> False- Just {} -> True--instance CanEmpty FilePath
− ClassyPrelude/HashMap.hs
@@ -1,62 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.HashMap- ( HashMap- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.Foldable as Foldable-import qualified Data.HashMap.Strict as HashMap---instance CanMap (HashMap k v1) (HashMap k v2) v1 v2 where- map = HashMap.map- -instance Hashable k => CanFilter (HashMap k v) (k, v) where- filter = HashMap.filterWithKey . curry- -instance CanLength (HashMap k v) Int where- length = HashMap.size- -instance (Eq k, Hashable k, v' ~ v) => CanSingleton (v' -> HashMap k v) k where- singleton = HashMap.singleton- -instance CanNull (HashMap k v) where- null = HashMap.null- -instance (Eq k, Hashable k) => CanPack (HashMap k v) (k, v) where- pack = HashMap.fromList- unpack = HashMap.toList- -instance (Eq k, Hashable k) => CanLookup (HashMap k v) k v where- lookup = HashMap.lookup- -instance (Eq k, Hashable k) => CanInsertVal (HashMap k v) k v where- insertVal = HashMap.insert- -instance (Eq k, Hashable k) => CanDeleteVal (HashMap k v) k where- deleteVal = HashMap.delete- -instance CanFind (HashMap k v) v where- find = Foldable.find- -instance (Monoid v) => CanConcat (HashMap k v) v where- concat = Foldable.fold- -instance Hashable k => CanPartition (HashMap k v) v where- partition p m = (HashMap.filter p m, HashMap.filter (not . p) m)--instance (Hashable k, Eq k) => CanUnion (HashMap k a) where- union = HashMap.union--instance (Hashable k, Eq k) => CanDifference (HashMap k a) where- difference = HashMap.difference--instance (Hashable k, Eq k) => CanIntersection (HashMap k a) where- intersection = HashMap.intersection--instance (Hashable k, Eq k) => CanEmpty (HashMap k a) where- empty = HashMap.empty
− ClassyPrelude/HashSet.hs
@@ -1,53 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.HashSet- ( HashSet- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.HashSet as HashSet-import qualified Control.Monad as Monad---instance (Eq b, Hashable b) => CanMap (HashSet a) (HashSet b) a b where- map = HashSet.map- -instance CanLength (HashSet x) Int where- length = HashSet.size--instance Hashable x => CanSingleton (HashSet x) x where- singleton = HashSet.singleton--instance CanNull (HashSet x) where- null = HashSet.null--instance (Hashable x, Eq x) => CanPack (HashSet x) x where- pack = HashSet.fromList- unpack = HashSet.toList--instance (Eq x, Hashable x, HashSet x ~ s, x ~ x') => CanInsert (x' -> s -> HashSet x) where- insert = HashSet.insert--instance (Eq x, Hashable x) => CanMember (HashSet x) x where- member = HashSet.member--instance CanFold (HashSet a) a accum where- fold = HashSet.foldl'--instance (Eq a, Hashable a) => CanMapM_ (HashSet a) a where- mapM_ f = Monad.mapM_ f . unpack--instance (Eq a, Hashable a) => CanUnion (HashSet a) where- union = HashSet.union--instance (Eq a, Hashable a) => CanDifference (HashSet a) where- difference = HashSet.difference--instance (Eq a, Hashable a) => CanIntersection (HashSet a) where- intersection = HashSet.intersection--instance (Eq a, Hashable a) => CanEmpty (HashSet a) where- empty = HashSet.empty
− ClassyPrelude/LByteString.hs
@@ -1,117 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.LByteString- ( LByteString- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.ByteString as ByteString-import qualified Filesystem.Path.CurrentOS as FilePath-import qualified Data.ByteString.Lazy as LByteString---instance CanMap LByteString LByteString Word8 Word8 where- map = LByteString.map--instance CanConcatMap LByteString LByteString Word8 LByteString where- concatMap = LByteString.concatMap--instance CanFilter LByteString Word8 where- filter = LByteString.filter--instance CanLength LByteString Int64 where- length = LByteString.length--instance CanSingleton LByteString Word8 where- singleton = LByteString.singleton--instance CanNull LByteString where- null = LByteString.null--instance CanPack LByteString Word8 where- pack = LByteString.pack- unpack = LByteString.unpack--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--instance CanWriteFile LByteString where- writeFile fp = liftIO . LByteString.writeFile (FilePath.encodeString fp)--instance CanBreak LByteString Word8 where- break = LByteString.break- span = LByteString.span- dropWhile = LByteString.dropWhile- takeWhile = LByteString.takeWhile--instance CanAny LByteString Word8 where- any = LByteString.any- all = LByteString.all--instance CanSplitAt LByteString Int64 where- splitAt = LByteString.splitAt--instance CanReverse LByteString where- reverse = LByteString.reverse--instance CanFold LByteString Word8 accum where- fold = LByteString.foldl'--instance CanReplicate LByteString Word8 Int64 where- replicate = LByteString.replicate--instance CanToChunks LByteString ByteString where- toChunks = LByteString.toChunks- fromChunks = LByteString.fromChunks--instance CanStripSuffix LByteString where- stripSuffix x y- | x `LByteString.isSuffixOf` y = Just (LByteString.take (LByteString.length y - LByteString.length x) y)- | otherwise = Nothing- isSuffixOf = LByteString.isSuffixOf--instance CanToStrict LByteString ByteString where- toStrict = ByteString.concat . toChunks- fromStrict = fromChunks . return--instance CanPartition LByteString Word8 where- partition = LByteString.partition--instance CanCons LByteString Word8 where- cons = LByteString.cons--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--instance CanZipWith LByteString Word8 LByteString Word8 [a] a where- zipWith = LByteString.zipWith--instance CanZip LByteString Word8 LByteString Word8 [] where- zip = LByteString.zip--instance CanUnzip LByteString Word8 LByteString Word8 [] where- unzip = LByteString.unzip--instance CanEmpty LByteString
− ClassyPrelude/LText.hs
@@ -1,141 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.LText- ( LText- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.Text.Lazy as LText-import qualified Data.Text.Lazy.IO as LText-import qualified Data.Text.Lazy.Encoding as LText-import qualified Data.Text.Encoding.Error as Text---instance CanMap LText LText Char Char where- map = LText.map--instance CanConcatMap LText LText Char LText where- concatMap = LText.concatMap--instance CanFilter LText Char where- filter = LText.filter--instance CanSingleton LText Char where- singleton = LText.singleton--instance CanNull LText where- null = LText.null--instance CanPack LText Char where- pack = LText.pack- unpack = LText.unpack--instance CanIntersperse LText Char where- intersperse = LText.intersperse--instance CanStripPrefix LText where- stripPrefix = LText.stripPrefix- isPrefixOf = LText.isPrefixOf--instance CanBreak LText Char where- break = LText.break- span = LText.span- dropWhile = LText.dropWhile- takeWhile = LText.takeWhile--instance CanAny LText Char where- any = LText.any- all = LText.all--instance CanSplitAt LText Int64 where- splitAt = LText.splitAt--instance CanWords LText where- words = LText.words- unwords = LText.unwords--instance CanLines LText where- lines = LText.lines--instance CanUnlines LText where- unlines = LText.unlines--instance CanSplit LText Char where- split = LText.split--instance CanStripSuffix LText where- stripSuffix = LText.stripSuffix- isSuffixOf = LText.isSuffixOf--instance CanIsInfixOf LText where- isInfixOf = LText.isInfixOf--instance CanReverse LText where- reverse = LText.reverse--instance CanLength LText Int64 where- length = LText.length--instance CanFold LText Char accum where- fold = LText.foldl'--instance CanReplicate LText LText Int64 where- replicate = LText.replicate--instance CanToChunks LText Text where- toChunks = LText.toChunks- fromChunks = LText.fromChunks--instance CanEncodeUtf8 LText LByteString where- encodeUtf8 = LText.encodeUtf8--instance CanDecodeUtf8 LByteString LText where- decodeUtf8 = LText.decodeUtf8With Text.lenientDecode--instance CanToStrict LText Text where- toStrict = LText.toStrict- fromStrict = LText.fromStrict--instance MonadIO m => CanGetLine (m LText) where- getLine = liftIO LText.getLine--instance CanToLower LText where- toLower = LText.toLower--instance CanToUpper LText where- toUpper = LText.toUpper--instance CanToCaseFold LText where- toCaseFold = LText.toCaseFold--instance CanFind LText Char where- find = LText.find--instance CanPartition LText Char where- partition = LText.partition--instance CanCons LText Char where- cons = LText.cons--instance CanUncons LText Char where- uncons = LText.uncons--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--instance CanZipWith LText Char LText Char LText Char where- zipWith = LText.zipWith--instance CanZip LText Char LText Char [] where- zip = LText.zip--instance CanEmpty LText
− ClassyPrelude/List.hs
@@ -1,224 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.List () where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.List as List-import qualified Control.Monad as Monad-import qualified Data.Monoid as Monoid-import qualified Data.Set as Set---instance CanMap [a] [b] a b where- map = List.map--instance CanConcatMap [a] [b] a [b] where- concatMap = List.concatMap--instance CanFilter [a] a where- filter = List.filter--instance CanFilterM [a] a where- filterM = Monad.filterM--instance CanLength [a] Int where- length = List.length--instance CanSingleton [a] a where- singleton = return--instance CanNull [a] where- null = List.null--instance CanPack [a] a where- pack = id- unpack = id- subsequences = List.subsequences- permutations = List.permutations--instance CanIntersperse [a] a where- intersperse = List.intersperse--instance Monad m => CanMapM [i] (m [o]) m i o where- mapM = Monad.mapM--instance CanMapM_ [a] a where- mapM_ = Monad.mapM_--instance Eq k => CanLookup [(k, v)] k v where- lookup = List.lookup--instance Eq k => CanInsertVal [(k, v)] k v where- insertVal k v c = (k, v) : delete k c--instance Eq k => CanDeleteVal [(k, v)] k where- deleteVal k = filter ((/= k) . fst)--instance Eq x => CanMember [x] x where- member x = List.any (== x)--instance Eq a => CanStripPrefix [a] where- stripPrefix = List.stripPrefix- isPrefixOf = List.isPrefixOf--instance CanBreak [a] a where- break = List.break- span = List.span- dropWhile = List.dropWhile- takeWhile = List.takeWhile--instance CanAny [a] a where- any = List.any- all = List.all--instance CanSplitAt [c] Int where- splitAt = List.splitAt--instance CanFold [a] a accum where- fold = List.foldl'--instance (c ~ Char) => CanWords [c] where- words = List.words- unwords = List.unwords--instance (c ~ Char) => CanLines [c] where- lines = List.lines--instance (c ~ Char) => CanUnlines [c] where- unlines = List.unlines--instance Eq a => CanIsInfixOf [a] where- isInfixOf = List.isInfixOf--instance CanReverse [a] where- reverse = List.reverse--instance CanReplicate [i] i Int where- replicate = List.replicate--instance CanReplicateM [a] a Int where- replicateM = Monad.replicateM--instance CanFind [a] a where- find = List.find--instance (Monoid m) => CanConcat [m] m where- concat = Monoid.mconcat--instance CanPartition [a] a where- partition = List.partition--instance CanNubBy [a] a where- nubBy = List.nubBy-- nub =- go Set.empty- where- go _ [] = []- go set (x:xs)- | x `Set.member` set = go set xs- | otherwise = x : go (Set.insert x set) xs--instance (Eq a) => CanUnion [a] where- union = List.union--instance (Eq a) => CanDifference [a] where- difference = (List.\\)--instance (Eq a) => CanIntersection [a] where- intersection = List.intersect--instance CanSortBy [a] a where- sortBy = List.sortBy-instance Ord a => CanSort [a] a where- sort = List.sort--instance CanCons [a] a where- cons = (:)--instance CanUncons [a] a where- uncons (head:tail) = Just (head, tail)- uncons _ = Nothing--instance CanCompareLength [a] where- compareLength [] 0 = EQ- compareLength _ i | i <= 0 = GT- compareLength [] _ = LT- compareLength (_:t) i = compareLength t (i-1)--instance CanGroupBy [a] a where- groupBy = List.groupBy--instance CanGroupBy' [a] a where- groupBy' f (head : tail) = let- (matches, nonMatches) = partition (f head) tail- in (head : matches) : groupBy' f nonMatches- groupBy' _ [] = []--instance Eq a => CanGroup [a] a where- group = List.group--instance Eq a => CanGroup' [a] a--instance CanRepeat [a] a where- repeat = List.repeat--instance CanZipWith [a] a [b] b [c] c where- zipWith = List.zipWith--instance CanZipWith3 [a] a [b] b [c] c [d] d where- zipWith3 = List.zipWith3--instance CanZipWith4 [a] a [b] b [c] c [d] d [e] e where- zipWith4 = List.zipWith4--instance CanZipWith5 [a] a [b] b [c] c [d] d [e] e [f] f where- zipWith5 = List.zipWith5--instance CanZipWith6 [a] a [b] b [c] c [d] d [e] e [f] f [g] g where- zipWith6 = List.zipWith6--instance CanZipWith7 [a] a [b] b [c] c [d] d [e] e [f] f [g] g [h] h where- zipWith7 = List.zipWith7--instance CanZip ([] a) a ([] b) b [] where- zip = List.zip--instance CanZip3 ([] a) a ([] b) b ([] c) c [] where- zip3 = List.zip3--instance CanZip4 ([] a) a ([] b) b ([] c) c ([] d) d [] where- zip4 = List.zip4--instance CanZip5 ([] a) a ([] b) b ([] c) c ([] d) d ([] e) e [] where- zip5 = List.zip5--instance CanZip6 ([] a) a ([] b) b ([] c) c ([] d) d ([] e) e ([] f) f [] where- zip6 = List.zip6--instance CanZip7 ([] a) a ([] b) b ([] c) c ([] d) d ([] e) e ([] f) f ([] g) g [] where- zip7 = List.zip7--instance CanUnzip ([] a) a ([] b) b [] where- unzip = List.unzip--instance CanUnzip3 ([] a) a ([] b) b ([] c) c [] where- unzip3 = List.unzip3--instance CanUnzip4 ([] a) a ([] b) b ([] c) c ([] d) d [] where- unzip4 = List.unzip4--instance CanUnzip5 ([] a) a ([] b) b ([] c) c ([] d) d ([] e) e [] where- unzip5 = List.unzip5--instance CanUnzip6 ([] a) a ([] b) b ([] c) c ([] d) d ([] e) e ([] f) f [] where- unzip6 = List.unzip6--instance CanUnzip7 ([] a) a ([] b) b ([] c) c ([] d) d ([] e) e ([] f) f ([] g) g [] where- unzip7 = List.unzip7--instance CanEmpty [a] where- empty = []
− ClassyPrelude/Map.hs
@@ -1,62 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.Map- ( Map- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.Foldable as Foldable-import qualified Data.Map as Map---instance CanMap (Map k v1) (Map k v2) v1 v2 where- map = Map.map--instance Ord k => CanFilter (Map k v) (k, v) where- filter = Map.filterWithKey . curry--instance CanLength (Map k v) Int where- length = Map.size--instance (v' ~ v) => CanSingleton (v' -> Map k v) k where- singleton = Map.singleton--instance CanNull (Map k v) where- null = Map.null--instance Ord k => CanPack (Map k v) (k, v) where- pack = Map.fromList- unpack = Map.toList--instance Ord k => CanLookup (Map k v) k v where- lookup = Map.lookup--instance Ord k => CanInsertVal (Map k v) k v where- insertVal = Map.insert--instance Ord k => CanDeleteVal (Map k v) k where- deleteVal = Map.delete--instance CanFind (Map k v) v where- find = Foldable.find--instance (Monoid v) => CanConcat (Map k v) v where- concat = Foldable.fold--instance Ord k => CanPartition (Map k v) v where- partition = Map.partition--instance (Ord k) => CanUnion (Map k a) where- union = Map.union--instance (Ord k) => CanDifference (Map k a) where- difference = Map.difference--instance (Ord k) => CanIntersection (Map k a) where- intersection = Map.intersection--instance (Ord k) => CanEmpty (Map k a) where- empty = Map.empty
− ClassyPrelude/Maybe.hs
@@ -1,63 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.Maybe () where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.Maybe as Maybe-import qualified Control.Monad as Monad-import qualified Data.Foldable as Foldable-import qualified Data.Traversable as Traversable---instance CanMap (Maybe a) (Maybe b) a b where- map = Monad.fmap--instance CanConcatMap (Maybe a) (Maybe b) a (Maybe b) where- concatMap = (Monad.=<<)--instance CanFilter (Maybe a) a where- filter = Monad.mfilter--instance CanLength (Maybe a) Int where- length a = if null a then 0 else 1--instance CanSingleton (Maybe a) a where- singleton = Monad.return--instance CanNull (Maybe a) where- null = Maybe.isNothing--instance CanPack (Maybe a) a where- pack = Maybe.listToMaybe- unpack = Maybe.maybeToList--instance Monad m => CanMapM (Maybe i) (m (Maybe o)) m i o where- mapM = Traversable.mapM--instance CanMapM_ (Maybe a) a where- mapM_ = Foldable.mapM_--instance Eq x => CanMember (Maybe x) x where- member = Foldable.elem--instance CanAny (Maybe a) a where- any = Foldable.any- all = Foldable.all--instance CanFold (Maybe a) a accum where- fold = Foldable.foldl'--instance Eq a => CanIsInfixOf (Maybe a) where- isInfixOf = (==)--instance CanReverse (Maybe a) where- reverse = id--instance CanFind (Maybe a) a where- find = Foldable.find--instance CanEmpty (Maybe a) where- empty = Nothing
− ClassyPrelude/Sequence.hs
@@ -1,156 +0,0 @@-{-# 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 Seq-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 = Seq.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)- Seq.empty--instance CanLength (Seq a) Int where- length = Seq.length--instance CanSingleton (Seq a) a where- singleton = Seq.singleton--instance CanNull (Seq a) where- null = Seq.null--instance CanPack (Seq a) a where- pack = Seq.fromList- unpack = Foldable.toList--instance CanIntersperse (Seq a) a where- intersperse sep xs = case viewl xs of- EmptyL -> Seq.empty- (h :< t) -> h <| prependToAll sep t- where- prependToAll sep xs = case viewl xs of- EmptyL -> Seq.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) = Seq.splitAt (Seq.length x) y- isPrefixOf x y = Seq.take (Seq.length x) y == x--instance Eq a => CanStripSuffix (Seq a) where- stripSuffix x y- | x == y2 = Just y1- | otherwise = Nothing- where- (y1, y2) = Seq.splitAt (Seq.length y - Seq.length x) y- isSuffixOf x y = takeRR (Seq.length x) y == x- where- takeRR 0 _ = Seq.empty- takeRR n xs = case viewr xs of- EmptyR -> Seq.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 = Seq.breakl- span = Seq.spanl- dropWhile = Seq.dropWhileL- takeWhile = Seq.takeWhileL--instance CanAny (Seq a) a where- any = Foldable.any- all = Foldable.all--instance CanSplitAt (Seq a) Int where- splitAt = Seq.splitAt--instance CanFold (Seq a) a accum where- fold = Foldable.foldl'--instance CanReverse (Seq a) where- reverse = Seq.reverse--instance CanReplicate (Seq a) a Int where- replicate = Seq.replicate--instance CanReplicateM (Seq a) a Int where- replicateM = Seq.replicateM--instance CanFind (Seq a) a where- find p s = case Seq.breakl p s of- (_, s') -> case Seq.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 = Seq.partition--instance CanSortBy (Seq a) a where- sortBy = Seq.sortBy--instance Ord a => CanSort (Seq a) a where- sort = Seq.sort--instance CanCons (Seq a) a where- cons = (<|)--instance CanUncons (Seq a) a where- uncons s = case Seq.viewl s of- EmptyL -> Nothing- a :< s' -> Just (a, s')--instance CanZipWith (Seq a) a (Seq b) b (Seq c) c where- zipWith = Seq.zipWith--instance CanZipWith3 (Seq a) a (Seq b) b (Seq c) c (Seq d) d where- zipWith3 = Seq.zipWith3--instance CanZipWith4 (Seq a) a (Seq b) b (Seq c) c (Seq d) d (Seq e) e where- zipWith4 = Seq.zipWith4--instance CanZip (Seq a) a (Seq b) b Seq where- zip = Seq.zip--instance CanZip3 (Seq a) a (Seq b) b (Seq c) c Seq where- zip3 = Seq.zip3--instance CanZip4 (Seq a) a (Seq b) b (Seq c) c (Seq d) d Seq where- zip4 = Seq.zip4--instance CanEmpty (Seq a) where- empty = Seq.empty
− ClassyPrelude/Set.hs
@@ -1,69 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.Set- ( Set- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Control.Monad as Monad-import qualified Data.Foldable as Foldable-import qualified Data.Set as Set---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--instance CanSingleton (Set x) x where- singleton = Set.singleton--instance CanNull (Set x) where- null = Set.null--instance Ord x => CanPack (Set x) x where- pack = Set.fromList- unpack = Set.toList--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--instance CanFold (Set a) a accum where- fold = Set.foldl'--instance Ord a => CanMapM_ (Set a) a where- mapM_ f = Monad.mapM_ f . unpack--instance CanFind (Set a) a where- find = Foldable.find--instance (Monoid m) => CanConcat (Set m) m where- concat = Foldable.fold--instance (Ord a) => CanPartition (Set a) a where- partition = Set.partition--instance (Ord a) => CanUnion (Set a) where- union = Set.union--instance (Ord a) => CanDifference (Set a) where- difference = Set.difference--instance (Ord a) => CanIntersection (Set a) where- intersection = Set.intersection--instance (Ord a) => CanEmpty (Set a) where- empty = Set.empty
− ClassyPrelude/Text.hs
@@ -1,133 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.Text- ( Text- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.Text as Text-import qualified Data.Text.Encoding as Text-import qualified Data.Text.Encoding.Error as Text-import qualified Data.Text.IO as Text---instance CanMap Text Text Char Char where- map = Text.map--instance CanConcatMap Text Text Char Text where- concatMap = Text.concatMap--instance CanFilter Text Char where- filter = Text.filter--instance CanLength Text Int where- length = Text.length--instance CanSingleton Text Char where- singleton = Text.singleton--instance CanNull Text where- null = Text.null--instance CanPack Text Char where- pack = Text.pack- unpack = Text.unpack--instance CanIntersperse Text Char where- intersperse = Text.intersperse--instance CanStripPrefix Text where- stripPrefix = Text.stripPrefix- isPrefixOf = Text.isPrefixOf--instance CanBreak Text Char where- break = Text.break- span = Text.span- dropWhile = Text.dropWhile- takeWhile = Text.takeWhile--instance CanAny Text Char where- any = Text.any- all = Text.all--instance CanSplitAt Text Int where- splitAt = Text.splitAt--instance CanWords Text where- words = Text.words- unwords = Text.unwords--instance CanLines Text where- lines = Text.lines--instance CanUnlines Text where- unlines = Text.unlines--instance CanSplit Text Char where- split = Text.split--instance CanStripSuffix Text where- stripSuffix = Text.stripSuffix- isSuffixOf = Text.isSuffixOf--instance CanIsInfixOf Text where- isInfixOf = Text.isInfixOf--instance CanReverse Text where- reverse = Text.reverse--instance CanFold Text Char accum where- fold = Text.foldl'--instance CanReplicate Text Text Int where- replicate = Text.replicate--instance CanEncodeUtf8 Text ByteString where- encodeUtf8 = Text.encodeUtf8- -instance CanDecodeUtf8 ByteString Text where- decodeUtf8 = Text.decodeUtf8With Text.lenientDecode--instance MonadIO m => CanGetLine (m Text) where- getLine = liftIO Text.getLine--instance CanToLower Text where- toLower = Text.toLower--instance CanToUpper Text where- toUpper = Text.toUpper--instance CanToCaseFold Text where- toCaseFold = Text.toCaseFold--instance CanFind Text Char where- find = Text.find--instance CanPartition Text Char where- partition = Text.partition--instance CanCons Text Char where- cons = Text.cons--instance CanUncons Text Char where- uncons = Text.uncons--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--instance CanZipWith Text Char Text Char Text Char where- zipWith = Text.zipWith--instance CanZip Text Char Text Char [] where- zip = Text.zip--instance CanEmpty Text
− ClassyPrelude/UVector.hs
@@ -1,185 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.UVector- ( UVector- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.Vector.Unboxed as UVector--instance (Unbox a, Unbox b) => CanMap (UVector a) (UVector b) a b where- map = UVector.map--instance (Unbox a, Unbox b) => CanConcatMap (UVector a) (UVector b) a (UVector b) where- concatMap = UVector.concatMap--instance (Unbox a) => CanFilter (UVector a) a where- filter = UVector.filter--instance (Unbox a) => CanFilterM (UVector a) a where- filterM = UVector.filterM--instance (Unbox a) => CanLength (UVector a) Int where- length = UVector.length--instance (Unbox a) => CanSingleton (UVector a) a where- singleton = UVector.singleton--instance (Unbox a) => CanNull (UVector a) where- null = UVector.null--instance (Unbox a) => CanPack (UVector a) a where- pack = UVector.fromList- unpack = UVector.toList--instance (Unbox a) => CanIntersperse (UVector a) a where- -- | Implementation is a rip off from <http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#intersperse>.- intersperse _ xs | null xs = UVector.empty- intersperse sep xs = UVector.cons (UVector.head xs) $ prependToAll sep $ UVector.unsafeTail xs- where- prependToAll _ xs | null xs = UVector.empty- prependToAll sep xs = UVector.cons sep $ UVector.cons (UVector.head xs) $ prependToAll sep $ UVector.unsafeTail xs--instance (Unbox a, Eq a) => CanStripPrefix (UVector a) where- stripPrefix x y- | x == y1 = Just y2- | otherwise = Nothing- where- (y1, y2) = UVector.splitAt (UVector.length x) y- isPrefixOf x y = UVector.take (UVector.length x) y == x--instance (Unbox i, Unbox o, Monad m) => CanMapM (UVector i) (m (UVector o)) m i o where- mapM = UVector.mapM--instance (Unbox a) => CanMapM_ (UVector a) a where- mapM_ = UVector.mapM_--instance (Unbox x, Eq x) => CanMember (UVector x) x where- member x = UVector.any (== x)--instance (Unbox a) => CanBreak (UVector a) a where- break = UVector.break- span = UVector.span- dropWhile = UVector.dropWhile- takeWhile = UVector.takeWhile--instance (Unbox a) => CanAny (UVector a) a where- any = UVector.any- all = UVector.all--instance (Unbox a) => CanSplitAt (UVector a) Int where- splitAt = UVector.splitAt--instance (Unbox a) => CanFold (UVector a) a accum where- fold = UVector.foldl'--instance (Unbox a) => CanReverse (UVector a) where- reverse = UVector.reverse--instance (Unbox a) => CanReplicate (UVector a) a Int where- replicate = UVector.replicate--instance (Unbox a) => CanReplicateM (UVector a) a Int where- replicateM = UVector.replicateM--instance (Unbox a) => CanFind (UVector a) a where- find = UVector.find- -instance (Unbox m, Monoid m) => CanConcat (UVector m) m where- concat = UVector.foldr mappend mempty--instance (Unbox a) => CanPartition (UVector a) a where- partition = UVector.partition--instance (Unbox a) => CanCons (UVector a) a where- cons = UVector.cons--instance (Unbox a) => CanUncons (UVector a) a where- uncons v = if null v then Nothing else Just (UVector.unsafeHead v, UVector.unsafeTail v)--instance (Unbox a) => CanGroupBy (UVector 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 UVector.unsafeTake n xs : groupBy k (UVector.unsafeDrop n xs))- xs--instance (Unbox a, Eq a) => CanGroup (UVector 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 =- UVector.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 (UVector.unsafeHead x) (UVector.unsafeTail x)---instance (Unbox a, Unbox b, Unbox c) => CanZipWith (UVector a) a (UVector b) b (UVector c) c where- zipWith = UVector.zipWith--instance (Unbox a, Unbox b, Unbox c, Unbox d) => CanZipWith3 (UVector a) a (UVector b) b (UVector c) c (UVector d) d where- zipWith3 = UVector.zipWith3--instance (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => CanZipWith4 (UVector a) a (UVector b) b (UVector c) c (UVector d) d (UVector e) e where- zipWith4 = UVector.zipWith4--instance (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => CanZipWith5 (UVector a) a (UVector b) b (UVector c) c (UVector d) d (UVector e) e (UVector f) f where- zipWith5 = UVector.zipWith5--instance (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f, Unbox g) => CanZipWith6 (UVector a) a (UVector b) b (UVector c) c (UVector d) d (UVector e) e (UVector f) f (UVector g) g where- zipWith6 = UVector.zipWith6--instance (Unbox a, Unbox b) => CanZip (UVector a) a (UVector b) b UVector where- zip = UVector.zip--instance (Unbox a, Unbox b, Unbox c) => CanZip3 (UVector a) a (UVector b) b (UVector c) c UVector where- zip3 = UVector.zip3--instance (Unbox a, Unbox b, Unbox c, Unbox d) => CanZip4 (UVector a) a (UVector b) b (UVector c) c (UVector d) d UVector where- zip4 = UVector.zip4--instance (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => CanZip5 (UVector a) a (UVector b) b (UVector c) c (UVector d) d (UVector e) e UVector where- zip5 = UVector.zip5--instance (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => CanZip6 (UVector a) a (UVector b) b (UVector c) c (UVector d) d (UVector e) e (UVector f) f UVector where- zip6 = UVector.zip6--instance (Unbox a, Unbox b) => CanUnzip (UVector a) a (UVector b) b UVector where- unzip = UVector.unzip--instance (Unbox a, Unbox b, Unbox c) => CanUnzip3 (UVector a) a (UVector b) b (UVector c) c UVector where- unzip3 = UVector.unzip3--instance (Unbox a, Unbox b, Unbox c, Unbox d) => CanUnzip4 (UVector a) a (UVector b) b (UVector c) c (UVector d) d UVector where- unzip4 = UVector.unzip4--instance (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => CanUnzip5 (UVector a) a (UVector b) b (UVector c) c (UVector d) d (UVector e) e UVector where- unzip5 = UVector.unzip5--instance (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => CanUnzip6 (UVector a) a (UVector b) b (UVector c) c (UVector d) d (UVector e) e (UVector f) f UVector where- unzip6 = UVector.unzip6--instance (Unbox a) => CanEmpty (UVector a) where- empty = UVector.empty
− ClassyPrelude/Vector.hs
@@ -1,187 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-module ClassyPrelude.Vector- ( Vector- ) where--import CorePrelude-import ClassyPrelude.Classes-import qualified Data.Foldable as Foldable-import qualified Data.Vector as Vector---instance CanMap (Vector a) (Vector b) a b where- map = Vector.map--instance CanConcatMap (Vector a) (Vector b) a (Vector b) where- concatMap = Vector.concatMap--instance CanFilter (Vector a) a where- filter = Vector.filter--instance CanFilterM (Vector a) a where- filterM = Vector.filterM--instance CanLength (Vector a) Int where- length = Vector.length--instance CanSingleton (Vector a) a where- singleton = Vector.singleton--instance CanNull (Vector a) where- null = Vector.null--instance CanPack (Vector a) a where- pack = Vector.fromList- unpack = Vector.toList--instance CanIntersperse (Vector a) a where- -- | Implementation is a rip off from <http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#intersperse>.- intersperse _ xs | null xs = Vector.empty- intersperse sep xs = Vector.cons (Vector.head xs) $ prependToAll sep $ Vector.unsafeTail xs- where- 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--instance CanMapM_ (Vector a) a where- mapM_ = Vector.mapM_--instance Eq x => CanMember (Vector x) x where- member x = Vector.any (== x)--instance CanBreak (Vector a) a where- break = Vector.break- span = Vector.span- dropWhile = Vector.dropWhile- takeWhile = Vector.takeWhile--instance CanAny (Vector a) a where- any = Vector.any- all = Vector.all--instance CanSplitAt (Vector a) Int where- splitAt = Vector.splitAt--instance CanFold (Vector a) a accum where- fold = Vector.foldl'--instance CanReverse (Vector a) where- reverse = Vector.reverse--instance CanReplicate (Vector a) a Int where- replicate = Vector.replicate--instance CanReplicateM (Vector a) a Int where- replicateM = Vector.replicateM--instance CanFind (Vector a) a where- find = Vector.find- -instance (Monoid m) => CanConcat (Vector m) m where- concat = Foldable.fold--instance CanPartition (Vector a) a where- partition = Vector.partition--instance CanCons (Vector a) a where- cons = Vector.cons--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)---instance CanZipWith (Vector a) a (Vector b) b (Vector c) c where- zipWith = Vector.zipWith--instance CanZipWith3 (Vector a) a (Vector b) b (Vector c) c (Vector d) d where- zipWith3 = Vector.zipWith3--instance CanZipWith4 (Vector a) a (Vector b) b (Vector c) c (Vector d) d (Vector e) e where- zipWith4 = Vector.zipWith4--instance CanZipWith5 (Vector a) a (Vector b) b (Vector c) c (Vector d) d (Vector e) e (Vector f) f where- zipWith5 = Vector.zipWith5--instance CanZipWith6 (Vector a) a (Vector b) b (Vector c) c (Vector d) d (Vector e) e (Vector f) f (Vector g) g where- zipWith6 = Vector.zipWith6--instance CanZip (Vector a) a (Vector b) b Vector where- zip = Vector.zip--instance CanZip3 (Vector a) a (Vector b) b (Vector c) c Vector where- zip3 = Vector.zip3--instance CanZip4 (Vector a) a (Vector b) b (Vector c) c (Vector d) d Vector where- zip4 = Vector.zip4--instance CanZip5 (Vector a) a (Vector b) b (Vector c) c (Vector d) d (Vector e) e Vector where- zip5 = Vector.zip5--instance CanZip6 (Vector a) a (Vector b) b (Vector c) c (Vector d) d (Vector e) e (Vector f) f Vector where- zip6 = Vector.zip6--instance CanUnzip (Vector a) a (Vector b) b Vector where- unzip = Vector.unzip--instance CanUnzip3 (Vector a) a (Vector b) b (Vector c) c Vector where- unzip3 = Vector.unzip3--instance CanUnzip4 (Vector a) a (Vector b) b (Vector c) c (Vector d) d Vector where- unzip4 = Vector.unzip4--instance CanUnzip5 (Vector a) a (Vector b) b (Vector c) c (Vector d) d (Vector e) e Vector where- unzip5 = Vector.unzip5--instance CanUnzip6 (Vector a) a (Vector b) b (Vector c) c (Vector d) d (Vector e) e (Vector f) f Vector where- unzip6 = Vector.unzip6--instance CanEmpty (Vector a) where- empty = Vector.empty
+ README.md view
@@ -0,0 +1,57 @@+classy-prelude+==============++A better Prelude. Haskell's Prelude needs to maintain backwards compatibility and has many aspects that no longer represents best practice. The goals of classy-prelude are:++* remove all partial functions+* modernize data structures+ * generally use Text instead of String+ * encourage the use of appropriate data structures such as Vectors or HashMaps instead of always using lists and associated lists+* reduce import lists and the need for qualified imports++classy-prelude [should only be used by application developers](http://www.yesodweb.com/blog/2013/10/prelude-replacements-libraries). Library authors should consider using [mono-traversable](https://github.com/snoyberg/mono-traversable/blob/master/README.md), which classy-prelude builds upon.++It is worth noting that classy-prelude [largely front-ran changes that the community made to the base Prelude in GHC 7.10](http://www.yesodweb.com/blog/2014/10/classy-base-prelude).++mono-traversable+================++Most of this functionality is provided by [mono-traversable](https://github.com/snoyberg/mono-traversable). Please read the README over there. classy-prelude gets rid of the `o` prefix from mono-traversable functions.+++Text+====++Lots of things use `Text` instead of `String`.+Note that `show` returns a `String`.+To get back `Text`, use `tshow`.+++other functionality+===================++* exceptions package+* system-filepath convenience functions+* whenM, unlessM+* hashNub and ordNub (efficient nub implementations).+++Using classy-prelude+====================++* use the NoImplicitPrelude extension (you can place this in your cabal file) and `import ClassyPrelude`+* use [base-noprelude](https://github.com/hvr/base-noprelude) in your project and define a Prelude module that re-exports `ClassyPrelude`.+++Appendix+========++* The [mono-traversable](https://github.com/snoyberg/mono-traversable) README.+* [The transition to the modern design of classy-prelude](http://www.yesodweb.com/blog/2013/09/classy-mono).++These blog posts contain some out-dated information but might be helpful+* [So many preludes!](http://www.yesodweb.com/blog/2013/01/so-many-preludes) (January 2013)+* [ClassyPrelude: The good, the bad, and the ugly](http://www.yesodweb.com/blog/2012/08/classy-prelude-good-bad-ugly) (August 2012)+++
classy-prelude.cabal view
@@ -1,61 +1,80 @@-name: classy-prelude-version: 0.5.10-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-license: MIT-license-file: LICENSE-author: Michael Snoyman-maintainer: michael@snoyman.com-category: Control, Prelude-build-type: Simple-cabal-version: >=1.8+cabal-version: 1.12 -library- exposed-modules: ClassyPrelude- ClassyPrelude.Classes- other-modules: ClassyPrelude.List- ClassyPrelude.ByteString- ClassyPrelude.LByteString- ClassyPrelude.Text- ClassyPrelude.LText- ClassyPrelude.Map- ClassyPrelude.Maybe- ClassyPrelude.Set- ClassyPrelude.FilePath- ClassyPrelude.Vector- ClassyPrelude.UVector- ClassyPrelude.HashMap- ClassyPrelude.HashSet- ClassyPrelude.Char- ClassyPrelude.Sequence- build-depends: base >= 4 && < 5- , basic-prelude >= 0.3.4 && < 0.4- , system-filepath >= 0.4 && < 0.5- , transformers- , containers >= 0.4.2- , text- , bytestring- , vector- , unordered-containers- , hashable- , lifted-base >= 0.2- , monad-control- , async >= 2.0- , deepseq- ghc-options: -Wall -fno-warn-orphans+-- This file has been generated from package.yaml by hpack version 0.35.1.+--+-- see: https://github.com/sol/hpack -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+name: classy-prelude+version: 1.5.0.3+synopsis: A typeclass-based Prelude.+description: See docs and README at <http://www.stackage.org/package/classy-prelude>+category: Control, Prelude+homepage: https://github.com/snoyberg/mono-traversable#readme+bug-reports: https://github.com/snoyberg/mono-traversable/issues+author: Michael Snoyman+maintainer: michael@snoyman.com+license: MIT+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md+ ChangeLog.md source-repository head- type: git- location: git://github.com/snoyberg/classy-prelude.git+ type: git+ location: https://github.com/snoyberg/mono-traversable++library+ exposed-modules:+ ClassyPrelude+ other-modules:+ Paths_classy_prelude+ hs-source-dirs:+ src+ ghc-options: -Wall -fno-warn-orphans+ build-depends:+ async+ , base >=4.13 && <5+ , basic-prelude >=0.7+ , bifunctors+ , bytestring+ , chunked-data >=0.3+ , containers >=0.4.2+ , deepseq+ , dlist >=0.7+ , ghc-prim+ , hashable+ , mono-traversable >=1.0+ , mono-traversable-instances+ , mtl+ , mutable-containers ==0.3.*+ , primitive+ , say+ , stm+ , stm-chans >=3+ , text+ , time >=1.5+ , transformers+ , unliftio >=0.2.1.0+ , unordered-containers+ , vector+ , vector-instances+ default-language: Haskell2010++test-suite test+ type: exitcode-stdio-1.0+ main-is: main.hs+ other-modules:+ Paths_classy_prelude+ hs-source-dirs:+ test+ ghc-options: -Wall+ build-depends:+ QuickCheck+ , base >=4.13 && <5+ , classy-prelude+ , containers+ , hspec >=1.3+ , transformers+ , unordered-containers+ default-language: Haskell2010
+ src/ClassyPrelude.hs view
@@ -0,0 +1,641 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeFamilies #-}+module ClassyPrelude+ ( -- * CorePrelude+ module CorePrelude+ , undefined+ -- * Standard+ -- ** Monoid+ , (++)+ -- ** Semigroup+ , Semigroup (..)+ , WrappedMonoid+ -- ** Functor+ , module Data.Functor+ -- ** Applicative+ , module Control.Applicative+ , (<&&>)+ , (<||>)+ -- ** Monad+ , module Control.Monad+ , whenM+ , unlessM+ -- ** UnliftIO reexports+ , module UnliftIO+ -- ** Mutable references+ , orElseSTM+ , module Data.Mutable+ -- ** STM Channels+ , module Control.Concurrent.STM.TBChan+ , module Control.Concurrent.STM.TBMChan+ , module Control.Concurrent.STM.TBMQueue+ , module Control.Concurrent.STM.TMChan+ , module Control.Concurrent.STM.TMQueue+ -- ** Primitive (exported since 0.9.4)+ , primToPrim+ , primToIO+ , primToST+ , module Data.Primitive.MutVar+ -- ** Debugging+ , trace+ , traceShow+ , traceId+ , traceM+ , traceShowId+ , traceShowM+ -- ** Time (since 0.6.1)+ , module Data.Time+#if MIN_VERSION_time(1,10,0)+ , parseTime+#endif+ -- ** Generics (since 0.8.1)+ , Generic+ -- ** Transformers (since 0.9.4)+ , Identity (..)+ , MonadReader+ , ask+ , asks+ , ReaderT (..)+ , Reader+ -- * Poly hierarchy+ , module Data.Foldable+ , module Data.Traversable+ -- ** Bifunctor (since 0.10.0)+ , module Data.Bifunctor+ -- * Mono hierarchy+ , module Data.MonoTraversable+ , module Data.MonoTraversable.Unprefixed+ , module Data.Sequences+ , module Data.Containers+ , module Data.Builder+ , module Data.NonNull+ , toByteVector+ , fromByteVector+ -- * I\/O+ , module Say+ -- * Concurrency+ , yieldThread+ , waitAsync+ , pollAsync+ , waitCatchAsync+ , linkAsync+ , link2Async+ -- * Non-standard+ -- ** List-like classes+ , map+ --, split+ , readMay+ , zip, zip3, zip4, zip5, zip6, zip7+ , unzip, unzip3, unzip4, unzip5, unzip6, unzip7+ , zipWith, zipWith3, zipWith4, zipWith5, zipWith6, zipWith7++ , hashNub+ , ordNub+ , ordNubBy++ , sortWith+ , Prelude.repeat+ -- ** Set-like+ , (\\)+ , intersect+ -- FIXME , mapSet+ -- ** Text-like+ , Show (..)+ , tshow+ , tlshow+ -- *** Case conversion+ , charToLower+ , charToUpper+ -- ** IO+ , readFile+ , readFileUtf8+ , writeFile+ , writeFileUtf8+ , hGetContents+ , hPut+ , hGetChunk+ , print+ -- Prelude IO operations+ , putChar+ , putStr+ , putStrLn+ , getChar+ , getLine+ , getContents+ , interact+ -- ** Difference lists+ , DList+ , asDList+ , applyDList+ -- ** Exceptions+ , module Control.DeepSeq+ -- ** Force types+ -- | Helper functions for situations where type inferer gets confused.+ , asByteString+ , asLByteString+ , asHashMap+ , asHashSet+ , asText+ , asLText+ , asList+ , asMap+ , asIntMap+ , asMaybe+ , asSet+ , asIntSet+ , asVector+ , asUVector+ , asSVector+ , asString+ ) where++import qualified Prelude+import Control.Applicative ((<**>),liftA,liftA2,liftA3,Alternative (..), optional)+import Data.Functor hiding (unzip)+import Control.Exception (assert)+import Control.DeepSeq (deepseq, ($!!), force, NFData (..))+import Control.Monad (when, unless, void, liftM, ap, forever, join, replicateM_, guard, MonadPlus (..), (=<<), (>=>), (<=<), liftM2, liftM3, liftM4, liftM5)+import qualified Control.Concurrent.STM as STM+import Data.Mutable+import Data.Traversable (Traversable (..), for, forM)+import Data.Foldable (Foldable)+import UnliftIO++import Data.Vector.Instances ()+import CorePrelude hiding+ ( putStr, putStrLn, print, undefined, (<>), catMaybes, first, second+ , catchIOError+ )+import Data.ChunkedZip+import qualified Data.Char as Char+import Data.Sequences+import Data.MonoTraversable+import Data.MonoTraversable.Unprefixed+import Data.MonoTraversable.Instances ()+import Data.Containers+import Data.Builder+import Data.NonNull+import qualified Data.ByteString+import qualified Data.Text.IO as TextIO+import qualified Data.Text.Lazy.IO as LTextIO+import Data.ByteString.Internal (ByteString (PS))+import Data.ByteString.Lazy.Internal (defaultChunkSize)+import Data.Vector.Storable (unsafeToForeignPtr, unsafeFromForeignPtr)++import qualified Debug.Trace as Trace+import Data.Semigroup (Semigroup (..), WrappedMonoid (..))+import Prelude (Show (..))+import Data.Time+ ( UTCTime (..)+ , Day (..)+ , toGregorian+ , fromGregorian+ , formatTime+#if !MIN_VERSION_time(1,10,0)+ , parseTime+#endif+ , parseTimeM+ , getCurrentTime+ , defaultTimeLocale+ )+import qualified Data.Time as Time++import qualified Data.Set as Set+import qualified Data.Map as Map+import qualified Data.HashSet as HashSet++import GHC.Generics (Generic)+import GHC.Stack (HasCallStack)++import Control.Monad.Primitive (primToPrim, primToIO, primToST)+import Data.Primitive.MutVar++import Data.Functor.Identity (Identity (..))+import Control.Monad.Reader (MonadReader, ask, asks, ReaderT (..), Reader)+import Data.Bifunctor+import Data.DList (DList)+import qualified Data.DList as DList+import Say+import Control.Concurrent.STM.TBChan+import Control.Concurrent.STM.TBMChan+import Control.Concurrent.STM.TBMQueue+import Control.Concurrent.STM.TMChan+import Control.Concurrent.STM.TMQueue+import qualified Control.Concurrent++tshow :: Show a => a -> Text+tshow = fromList . Prelude.show++tlshow :: Show a => a -> LText+tlshow = fromList . Prelude.show++-- | Convert a character to lower case.+--+-- Character-based case conversion is lossy in comparison to string-based 'Data.MonoTraversable.toLower'.+-- For instance, İ will be converted to i, instead of i̇.+charToLower :: Char -> Char+charToLower = Char.toLower++-- | Convert a character to upper case.+--+-- Character-based case conversion is lossy in comparison to string-based 'Data.MonoTraversable.toUpper'.+-- For instance, ß won't be converted to SS.+charToUpper :: Char -> Char+charToUpper = Char.toUpper++readMay :: (Element c ~ Char, MonoFoldable c, Read a) => c -> Maybe a+readMay a = -- FIXME replace with safe-failure stuff+ case [x | (x, t) <- Prelude.reads (otoList a :: String), onull t] of+ [x] -> Just x+ _ -> Nothing++map :: Functor f => (a -> b) -> f a -> f b+map = fmap++infixr 5 +++(++) :: Monoid m => m -> m -> m+(++) = mappend+{-# INLINE (++) #-}++infixl 9 \\{-This comment teaches CPP correct behaviour -}+-- | An alias for 'difference'.+(\\) :: SetContainer a => a -> a -> a+(\\) = difference+{-# INLINE (\\) #-}++-- | An alias for 'intersection'.+intersect :: SetContainer a => a -> a -> a+intersect = intersection+{-# INLINE intersect #-}++asByteString :: ByteString -> ByteString+asByteString = id++asLByteString :: LByteString -> LByteString+asLByteString = id++asHashMap :: HashMap k v -> HashMap k v+asHashMap = id++asHashSet :: HashSet a -> HashSet a+asHashSet = id++asText :: Text -> Text+asText = id++asLText :: LText -> LText+asLText = id++asList :: [a] -> [a]+asList = id++asMap :: Map k v -> Map k v+asMap = id++asIntMap :: IntMap v -> IntMap v+asIntMap = id++asMaybe :: Maybe a -> Maybe a+asMaybe = id++asSet :: Set a -> Set a+asSet = id++asIntSet :: IntSet -> IntSet+asIntSet = id++asVector :: Vector a -> Vector a+asVector = id++asUVector :: UVector a -> UVector a+asUVector = id++asSVector :: SVector a -> SVector a+asSVector = id++asString :: [Char] -> [Char]+asString = id++print :: (Show a, MonadIO m) => a -> m ()+print = liftIO . Prelude.print++-- | Sort elements using the user supplied function to project something out of+-- each element.+-- Inspired by <http://hackage.haskell.org/packages/archive/base/latest/doc/html/GHC-Exts.html#v:sortWith>.+sortWith :: (Ord a, IsSequence c) => (Element c -> a) -> c -> c+sortWith f = sortBy $ comparing f++-- | We define our own 'undefined' which is marked as deprecated. This makes it+-- useful to use during development, but lets you more easily get+-- notifications if you accidentally ship partial code in production.+--+-- The classy prelude recommendation for when you need to really have a partial+-- function in production is to use 'error' with a very descriptive message so+-- that, in case an exception is thrown, you get more information than+-- @"Prelude".'Prelude.undefined'@.+--+-- Since 0.5.5+undefined :: HasCallStack => a+undefined = error "ClassyPrelude.undefined"+{-# DEPRECATED undefined "It is highly recommended that you either avoid partial functions or provide meaningful error messages" #-}++-- | We define our own 'trace' (and also its variants) which provides a warning+-- when used. So that tracing is available during development, but the compiler+-- reminds you to not leave them in the code for production.+{-# WARNING trace "Leaving traces in the code" #-}+trace :: String -> a -> a+trace = Trace.trace++{-# WARNING traceShow "Leaving traces in the code" #-}+traceShow :: Show a => a -> b -> b+traceShow = Trace.traceShow++-- |+--+-- Since 0.5.9+{-# WARNING traceId "Leaving traces in the code" #-}+traceId :: String -> String+traceId a = Trace.trace a a++-- |+--+-- Since 0.5.9+{-# WARNING traceM "Leaving traces in the code" #-}+traceM :: (Monad m) => String -> m ()+traceM string = Trace.trace string $ return ()++-- |+--+-- Since 0.5.9+{-# WARNING traceShowId "Leaving traces in the code" #-}+traceShowId :: (Show a) => a -> a+traceShowId a = Trace.trace (show a) a++-- |+--+-- Since 0.5.9+{-# WARNING traceShowM "Leaving traces in the code" #-}+traceShowM :: (Show a, Monad m) => a -> m ()+traceShowM = traceM . show++-- | Originally 'Conc.yield'.+yieldThread :: MonadIO m => m ()+yieldThread = liftIO Control.Concurrent.yield+{-# INLINE yieldThread #-}++-- Below is a lot of coding for classy-prelude!+-- These functions are restricted to lists right now.+-- Should eventually exist in mono-foldable and be extended to MonoFoldable+-- when doing that should re-run the haskell-ordnub benchmarks++-- | same behavior as 'Data.List.nub', but requires 'Hashable' & 'Eq' and is @O(n log n)@+--+-- <https://github.com/nh2/haskell-ordnub>+hashNub :: (Hashable a, Eq a) => [a] -> [a]+hashNub = go HashSet.empty+ where+ go _ [] = []+ go s (x:xs) | x `HashSet.member` s = go s xs+ | otherwise = x : go (HashSet.insert x s) xs++-- | same behavior as 'Data.List.nub', but requires 'Ord' and is @O(n log n)@+--+-- <https://github.com/nh2/haskell-ordnub>+ordNub :: (Ord a) => [a] -> [a]+ordNub = go Set.empty+ where+ go _ [] = []+ go s (x:xs) | x `Set.member` s = go s xs+ | otherwise = x : go (Set.insert x s) xs++-- | same behavior as 'Data.List.nubBy', but requires 'Ord' and is @O(n log n)@+--+-- <https://github.com/nh2/haskell-ordnub>+ordNubBy :: (Ord b) => (a -> b) -> (a -> a -> Bool) -> [a] -> [a]+ordNubBy p f = go Map.empty+ -- When removing duplicates, the first function assigns the input to a bucket,+ -- the second function checks whether it is already in the bucket (linear search).+ where+ go _ [] = []+ go m (x:xs) = let b = p x in case b `Map.lookup` m of+ Nothing -> x : go (Map.insert b [x] m) xs+ Just bucket+ | elem_by f x bucket -> go m xs+ | otherwise -> x : go (Map.insert b (x:bucket) m) xs++ -- From the Data.List source code.+ elem_by :: (a -> a -> Bool) -> a -> [a] -> Bool+ elem_by _ _ [] = False+ elem_by eq y (x:xs) = y `eq` x || elem_by eq y xs++-- | Synonym for 'STM.orElse'.+orElseSTM :: STM a -> STM a -> STM a+orElseSTM = STM.orElse+{-# INLINE orElseSTM #-}++-- | Only perform the action if the predicate returns 'True'.+--+-- Since 0.9.2+whenM :: Monad m => m Bool -> m () -> m ()+whenM mbool action = mbool >>= flip when action++-- | Only perform the action if the predicate returns 'False'.+--+-- Since 0.9.2+unlessM :: Monad m => m Bool -> m () -> m ()+unlessM mbool action = mbool >>= flip unless action++-- | Force type to a 'DList'+--+-- Since 0.11.0+asDList :: DList a -> DList a+asDList = id+{-# INLINE asDList #-}++-- | Synonym for 'DList.apply'+--+-- Since 0.11.0+applyDList :: DList a -> [a] -> [a]+applyDList = DList.apply+{-# INLINE applyDList #-}++infixr 3 <&&>+-- | '&&' lifted to an Applicative.+--+-- @since 0.12.8+(<&&>) :: Applicative a => a Bool -> a Bool -> a Bool+(<&&>) = liftA2 (&&)+{-# INLINE (<&&>) #-}++infixr 2 <||>+-- | '||' lifted to an Applicative.+--+-- @since 0.12.8+(<||>) :: Applicative a => a Bool -> a Bool -> a Bool+(<||>) = liftA2 (||)+{-# INLINE (<||>) #-}++-- | Convert a 'ByteString' into a storable 'Vector'.+toByteVector :: ByteString -> SVector Word8+toByteVector (PS fptr offset idx) = unsafeFromForeignPtr fptr offset idx+{-# INLINE toByteVector #-}++-- | Convert a storable 'Vector' into a 'ByteString'.+fromByteVector :: SVector Word8 -> ByteString+fromByteVector v =+ PS fptr offset idx+ where+ (fptr, offset, idx) = unsafeToForeignPtr v+{-# INLINE fromByteVector #-}++-- | 'waitSTM' for any 'MonadIO'+--+-- @since 1.0.0+waitAsync :: MonadIO m => Async a -> m a+waitAsync = atomically . waitSTM++-- | 'pollSTM' for any 'MonadIO'+--+-- @since 1.0.0+pollAsync :: MonadIO m => Async a -> m (Maybe (Either SomeException a))+pollAsync = atomically . pollSTM++-- | 'waitCatchSTM' for any 'MonadIO'+--+-- @since 1.0.0+waitCatchAsync :: MonadIO m => Async a -> m (Either SomeException a)+waitCatchAsync = waitCatch++-- | 'Async.link' generalized to any 'MonadIO'+--+-- @since 1.0.0+linkAsync :: MonadIO m => Async a -> m ()+linkAsync = UnliftIO.link++-- | 'Async.link2' generalized to any 'MonadIO'+--+-- @since 1.0.0+link2Async :: MonadIO m => Async a -> Async b -> m ()+link2Async a = UnliftIO.link2 a++-- | Strictly read a file into a 'ByteString'.+--+-- @since 1.2.0+readFile :: MonadIO m => FilePath -> m ByteString+readFile = liftIO . Data.ByteString.readFile++-- | Strictly read a file into a 'Text' using a UTF-8 character+-- encoding. In the event of a character encoding error, a Unicode+-- replacement character will be used (a.k.a., @lenientDecode@).+--+-- @since 1.2.0+readFileUtf8 :: MonadIO m => FilePath -> m Text+readFileUtf8 = liftM decodeUtf8 . readFile++-- | Write a 'ByteString' to a file.+--+-- @since 1.2.0+writeFile :: MonadIO m => FilePath -> ByteString -> m ()+writeFile fp = liftIO . Data.ByteString.writeFile fp++-- | Write a 'Text' to a file using a UTF-8 character encoding.+--+-- @since 1.2.0+writeFileUtf8 :: MonadIO m => FilePath -> Text -> m ()+writeFileUtf8 fp = writeFile fp . encodeUtf8++-- | Strictly read the contents of the given 'Handle' into a+-- 'ByteString'.+--+-- @since 1.2.0+hGetContents :: MonadIO m => Handle -> m ByteString+hGetContents = liftIO . Data.ByteString.hGetContents++-- | Write a 'ByteString' to the given 'Handle'.+--+-- @since 1.2.0+hPut :: MonadIO m => Handle -> ByteString -> m ()+hPut h = liftIO . Data.ByteString.hPut h++-- | Read a single chunk of data as a 'ByteString' from the given+-- 'Handle'.+--+-- Under the surface, this uses 'Data.ByteString.hGetSome' with the+-- default chunk size.+--+-- @since 1.2.0+hGetChunk :: MonadIO m => Handle -> m ByteString+hGetChunk = liftIO . flip Data.ByteString.hGetSome defaultChunkSize++-- | Write a character to stdout+--+-- Uses system locale settings+--+-- @since 1.3.1+putChar :: MonadIO m => Char -> m ()+putChar = liftIO . Prelude.putChar++-- | Write a Text to stdout+--+-- Uses system locale settings+--+-- @since 1.3.1+putStr :: MonadIO m => Text -> m ()+putStr = liftIO . TextIO.putStr++-- | Write a Text followed by a newline to stdout+--+-- Uses system locale settings+--+-- @since 1.3.1+putStrLn :: MonadIO m => Text -> m ()+putStrLn = liftIO . TextIO.putStrLn++-- | Read a character from stdin+--+-- Uses system locale settings+--+-- @since 1.3.1+getChar :: MonadIO m => m Char+getChar = liftIO Prelude.getChar++-- | Read a line from stdin+--+-- Uses system locale settings+--+-- @since 1.3.1+getLine :: MonadIO m => m Text+getLine = liftIO TextIO.getLine++-- | Read all input from stdin into a lazy Text ('LText')+--+-- Uses system locale settings+--+-- @since 1.3.1+getContents :: MonadIO m => m LText+getContents = liftIO LTextIO.getContents++-- | Takes a function of type 'LText -> LText' and passes all input on stdin+-- to it, then prints result to stdout+--+-- Uses lazy IO+-- Uses system locale settings+--+-- @since 1.3.1+interact :: MonadIO m => (LText -> LText) -> m ()+interact = liftIO . LTextIO.interact+++#if MIN_VERSION_time(1,10,0)+parseTime + :: Time.ParseTime t+ => Time.TimeLocale -- ^ Time locale.+ -> String -- ^ Format string.+ -> String -- ^ Input string.+ -> Maybe t -- ^ The time value, or 'Nothing' if the input could not be parsed using the given format.+parseTime = parseTimeM True+#endif++
test/main.hs view
@@ -1,110 +1,93 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE PatternGuards #-}+{-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -fno-warn-orphans #-} import Test.Hspec import Test.Hspec.QuickCheck import ClassyPrelude hiding (undefined)-import ClassyPrelude.Classes import Test.QuickCheck.Arbitrary-import Prelude (asTypeOf, fromIntegral, undefined)-import qualified Prelude+import Prelude (undefined) import Control.Monad.Trans.Writer (tell, Writer, runWriter)-import Data.Maybe (isJust)-import Data.Functor.Identity (runIdentity)-import Control.Concurrent (throwTo, threadDelay, forkIO)-import Control.Exception (throw)+import qualified Data.Set as Set+import qualified Data.HashSet as HashSet dictionaryProps- :: ( CanInsertVal a Int Char- , CanDeleteVal a Int- , CanEmpty a- , Show a- , Eq a- , Arbitrary a- , Monoid a- , CanLookup a Int Char- , CanPack a (Int, Char)+ :: ( MapValue c ~ Char+ , ContainerKey c ~ Int+ , Arbitrary c+ , IsMap c+ , Eq c+ , Show c )- => a -> Spec+ => c+ -> 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 ->- pack (unpack $ delete x (insert x y (c `asTypeOf` dummy))) == (pack (unpack ((delete x c) `asTypeOf` dummy) :: [(Int, Char)]) `asTypeOf` dummy)- 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+ insertMap x y (insertMap x z (c `asTypeOf` dummy)) == insertMap x y c+ prop "insertMap x y (deleteMap x c) == insertMap x y c" $ \x y c ->+ insertMap x y (deleteMap x (c `asTypeOf` dummy)) == insertMap x y c+ prop "deleteMap x (insertMap x y c) == deleteMap x c" $ \x y c ->+ mapFromList (mapToList $ deleteMap x (insertMap x y (c `asTypeOf` dummy))) == (mapFromList (mapToList ((deleteMap x c) `asTypeOf` dummy) :: [(Int, Char)]) `asTypeOf` dummy)+ prop "lookup k (insertMap k v empty) == Just v" $ \k v ->+ lookup k (insertMap k v mempty `asTypeOf` dummy) == Just v+ prop "lookup k (deleteMap k c) == Nothing" $ \k c ->+ lookup k (deleteMap k c`asTypeOf` dummy) == Nothing -mapProps :: ( CanPack a i- , CanPack b j- , Eq a+mapProps :: ( i ~ Element c+ , MonoFoldable c , Eq c- , Show a- , Arbitrary a- , Eq b- , Show b- , Arbitrary b- , CanMap a b i j- , CanMap a c i k- , CanMap b c j k+ , Arbitrary c+ , Show c )- => a- -> (i -> j)- -> (j -> k)+ => ((i -> i) -> c -> c)+ -> ([i] -> c)+ -> c+ -> (i -> i)+ -> (i -> i) -> Spec-mapProps dummy f g = do+mapProps map' pack' dummy f g = do prop "map f c == pack (map f (unpack c))" $ \c ->- map f (c `asTypeOf` dummy) == pack (map f (unpack c))+ map' f (c `asTypeOf` dummy) == pack' (fmap 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)+ 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- , CanMap a b i j- , CanConcatMap a b i js- )- => a- -> (i -> js)- -> Spec+concatMapProps :: ( MonoFoldable c+ , IsSequence c+ , Eq c+ , Arbitrary c+ , Show c+ )+ => c+ -> (Element c -> c)+ -> 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- , CanFilter a i+filterProps :: ( Eq c+ , Show c+ , IsSequence c+ , Arbitrary c )- => a- -> (i -> Bool)+ => c+ -> (Element c -> Bool) -> Spec filterProps dummy f = do 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- , CanFilterM a i+filterMProps :: ( Eq c+ , Show c+ , IsSequence c+ , Arbitrary c )- => a- -> (i -> Bool)+ => c+ -> (Element c -> Bool) -> Spec filterMProps dummy f' = do prop "filterM f c == fmap pack (filterM f (unpack c))" $ \c ->@@ -112,19 +95,13 @@ where f = return . f' -lengthProps :: ( Show a- , Eq a- , Arbitrary a- , CanPack a i- , CanLength a len- , CanEmpty a- , Prelude.Num len- , Eq len- , CanNull a- , Ord len- , Monoid a+lengthProps :: ( Show c+ , MonoFoldable c+ , Monoid c+ , Arbitrary c )- => a -> Spec+ => c+ -> Spec lengthProps dummy = do prop "length c == fromIntegral (length (unpack c))" $ \c -> length (c `asTypeOf` dummy) == fromIntegral (length (unpack c))@@ -135,93 +112,108 @@ 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)+ length (x ++ mempty `asTypeOf` dummy) == length x+ prop "null empty" $ null (mempty `asTypeOf` dummy) -{--mapMProps :: ( Show a- , Arbitrary a- , CanPack a i- , Eq i- , CanMapM a co i i- , CanPack co i- , Eq co+mapMProps :: ( Eq c+ , Show c+ , IsSequence c+ , Arbitrary c+ , Element c ~ Int )- => a -> Spec--}+ => c+ -> 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))+ prop "omapM f c == omapM f (toList c)" $ \c ->+ runWriter (omapM f (c `asTypeOf` dummy)) ==+ let (x, y) = runWriter (omapM f (toList c)) in (pack x, y) -mapM_Props :: ( Show a- , Arbitrary a- , CanPack a i- , Eq i- , CanMapM_ a i+mapM_Props :: ( Eq (Element c)+ , Show c+ , MonoFoldable c+ , Arbitrary c )- => a -> Spec+ => c+ -> 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 :: ( Eq a+ , Show c+ , MonoFoldable c+ , Arbitrary c+ )+ => c+ -> (a -> Element c -> a)+ -> a+ -> Spec 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)+ prop "foldl' f accum c == foldl' f accum (toList c)" $ \c ->+ foldl' f accum (c `asTypeOf` dummy) == foldl' f accum (toList c) -replicateProps :: ( Show a- , Eq a- , CanReplicate a i len- , Integral len- , Show len- , Arbitrary len- , Show i- , Arbitrary i+replicateProps :: ( Eq a+ , Show (Element c)+ , IsSequence a+ , IsSequence c+ , Arbitrary (Element c)+ , Element a ~ Element c )- => a -> ([i] -> a) -> Spec+ => a+ -> (c -> 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)+ (replicate i a `asTypeOf` dummy) == pack' (replicate i a) where i = 3 chunkProps :: ( Eq a , Show a , Arbitrary a- , CanToChunks a i- , Monoid i- ) => a -> Spec+ , LazySequence a s+ )+ => a+ -> Spec chunkProps dummy = do prop "fromChunks . toChunks == id" $ \a -> fromChunks (toChunks (a `asTypeOf` dummy)) == a 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+suffixProps :: ( Eq c+ , Show c+ , Arbitrary c+ , IsSequence c+ , Eq (Element c)+ )+ => c+ -> Spec+suffixProps dummy = do+ prop "y `isSuffixOf` (x ++ y)" $ \x y ->+ (y `asTypeOf` dummy) `isSuffixOf` (x ++ y) 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)+ prop "dropSuffix y (x ++ y) == x" $ \x y ->+ dropSuffix y (x ++ y) == (x `asTypeOf` dummy)+ prop "dropSuffix x y == y || x `isSuffixOf` y" $ \x y ->+ dropSuffix x y == y || x `isSuffixOf` (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 :: ( Eq a+ , Show (Index a)+ , Show (Element a)+ , IsSequence a+ , Arbitrary (Index a)+ , Arbitrary (Element a)+ )+ => a+ -> Spec replicateMProps dummy = do prop "runIdentity (replicateM i (return x)) == replicate i x" $ \i' x -> let i = i' `mod` 20@@ -230,32 +222,33 @@ utf8Props :: ( Eq t , Show t , Arbitrary t- , CanEncodeUtf8 t b- , CanDecodeUtf8 b t- ) => t -> Spec+ , Textual t+ , Utf8 t b+ )+ => t+ -> Spec utf8Props dummy = do prop "decodeUtf8 . encodeUtf8 == id" $ \t -> decodeUtf8 (encodeUtf8 t) == (t `asTypeOf` dummy) -compareLengthProps :: ( Show c+compareLengthProps :: ( MonoFoldable c , Arbitrary c- , CanCompareLength c- , Show l- , Arbitrary l- , Integral l- , CanLength c l- ) => c -> Spec+ , Show c+ )+ => c+ -> Spec compareLengthProps dummy = do 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+prefixProps :: ( Eq c+ , IsSequence c+ , Eq (Element c) , Arbitrary c+ , Show c )- => c -> Spec+ => c+ -> Spec prefixProps dummy = do prop "x `isPrefixOf` (x ++ y)" $ \x y -> (x `asTypeOf` dummy) `isPrefixOf` (x ++ y)@@ -263,6 +256,10 @@ 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)+ prop "dropPrefix x (x ++ y) == y" $ \x y ->+ dropPrefix x (x ++ y) == (y `asTypeOf` dummy)+ prop "dropPrefix x y == y || x `isPrefixOf` y" $ \x y ->+ dropPrefix x y == y || x `isPrefixOf` (y `asTypeOf` dummy) main :: IO () main = hspec $ do@@ -271,16 +268,16 @@ 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.Vector.Unboxed" $ mapProps (undefined :: UVector 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 "Data.Sequence" $ mapProps (undefined :: Seq Int) succ succ+ describe "list" $ mapProps fmap pack (undefined :: [Int]) (+ 1) (+ 2)+ describe "Data.Vector" $ mapProps fmap pack (undefined :: Vector Int) (+ 1) (+ 2)+ describe "Data.Vector.Unboxed" $ mapProps omap pack (undefined :: UVector Int) (+ 1) (+ 2)+ describe "Data.Set" $ mapProps Set.map setFromList (undefined :: Set Int) (+ 1) (+ 2)+ describe "Data.HashSet" $ mapProps HashSet.map setFromList (undefined :: HashSet Int) (+ 1) (+ 2)+ describe "Data.ByteString" $ mapProps omap pack (undefined :: ByteString) (+ 1) (+ 2)+ describe "Data.ByteString.Lazy" $ mapProps omap pack (undefined :: LByteString) (+ 1) (+ 2)+ describe "Data.Text" $ mapProps omap pack (undefined :: Text) succ succ+ describe "Data.Text.Lazy" $ mapProps omap pack (undefined :: LText) succ succ+ describe "Data.Sequence" $ mapProps fmap pack (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])@@ -298,9 +295,11 @@ describe "Data.ByteString.Lazy" $ filterProps (undefined :: LByteString) (< 20) describe "Data.Text" $ filterProps (undefined :: Text) (< 'A') describe "Data.Text.Lazy" $ filterProps (undefined :: LText) (< 'A')+ {- FIXME 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)@@ -350,18 +349,21 @@ describe "Data.Vector.Unboxed" $ replicateProps (undefined :: UVector 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+ describe "Data.Text" $ replicateProps (undefined :: Text) pack+ describe "Data.Text.Lazy" $ replicateProps (undefined :: LText) pack describe "Data.Sequence" $ replicateProps (undefined :: Seq Int) pack 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 "Seq" $ stripSuffixProps (undefined :: Seq Int)+ describe "Suffix" $ do+ describe "list" $ suffixProps (undefined :: [Int])+ describe "Text" $ suffixProps (undefined :: Text)+ describe "LText" $ suffixProps (undefined :: LText)+ describe "ByteString" $ suffixProps (undefined :: ByteString)+ describe "LByteString" $ suffixProps (undefined :: LByteString)+ describe "Vector" $ suffixProps (undefined :: Vector Int)+ describe "UVector" $ suffixProps (undefined :: UVector Int)+ describe "Seq" $ suffixProps (undefined :: Seq Int) describe "replicateM" $ do describe "list" $ replicateMProps (undefined :: [Int]) describe "Vector" $ replicateMProps (undefined :: Vector Int)@@ -383,6 +385,8 @@ describe "Vector" $ prefixProps (undefined :: Vector Int) describe "UVector" $ prefixProps (undefined :: UVector Int) describe "Seq" $ prefixProps (undefined :: Seq Int)+ {- This tests depend on timing and are unreliable. Instead, we're relying+ on the test suite in safe-exceptions itself. describe "any exceptions" $ do it "catchAny" $ do failed <- newIORef 0@@ -395,7 +399,7 @@ throwTo tid DummyException threadDelay 50000 didFail <- readIORef failed- liftIO $ didFail `shouldBe` 0+ liftIO $ didFail `shouldBe` (0 :: Int) it "tryAny" $ do failed <- newIORef False tid <- forkIO $ do@@ -407,29 +411,40 @@ didFail <- readIORef failed liftIO $ didFail `shouldBe` False it "tryAnyDeep" $ do- eres <- tryAnyDeep $ return $ throw DummyException+ eres <- tryAny $ return $!! impureThrow DummyException case eres of Left e | Just DummyException <- fromException e -> return () | otherwise -> error "Expected a DummyException" Right () -> error "Expected an exception" :: IO ()+ -}+ it "basic DList functionality" $+ (toList $ asDList $ mconcat+ [ fromList [1, 2]+ , singleton 3+ , cons 4 mempty+ , fromList $ applyDList (singleton 5 ++ singleton 6) [7, 8]+ ]) `shouldBe` [1..8 :: Int] + describe "Data.ByteVector" $ do+ prop "toByteVector" $ \ws ->+ (otoList . toByteVector . fromList $ ws) `shouldBe` ws++ prop "fromByteVector" $ \ws ->+ (otoList . fromByteVector . fromList $ ws) `shouldBe` ws+ data DummyException = DummyException deriving (Show, Typeable) instance Exception DummyException -instance Arbitrary (Map Int Char) where- arbitrary = fromList <$> arbitrary instance Arbitrary (HashMap Int Char) where- arbitrary = fromList <$> arbitrary+ arbitrary = mapFromList <$> arbitrary instance Arbitrary (Vector Int) where arbitrary = fromList <$> arbitrary instance Arbitrary (UVector Int) where arbitrary = fromList <$> arbitrary-instance Arbitrary (Set Int) where- arbitrary = fromList <$> arbitrary instance Arbitrary (HashSet Int) where- arbitrary = fromList <$> arbitrary+ arbitrary = setFromList <$> arbitrary instance Arbitrary ByteString where arbitrary = fromList <$> arbitrary instance Arbitrary LByteString where@@ -438,5 +453,12 @@ arbitrary = fromList <$> arbitrary instance Arbitrary LText where arbitrary = fromList <$> arbitrary++#if !MIN_VERSION_QuickCheck(2,8,2) instance Arbitrary (Seq Int) where arbitrary = fromList <$> arbitrary+instance Arbitrary (Set Int) where+ arbitrary = setFromList <$> arbitrary+instance Arbitrary (Map Int Char) where+ arbitrary = mapFromList <$> arbitrary+#endif