{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
module ClassyPrelude
(
module CorePrelude
, undefined
, (++)
, Semigroup (..)
, WrappedMonoid
, module Data.Functor
, module Control.Applicative
, (<&&>)
, (<||>)
, module Control.Monad
, whenM
, unlessM
, module UnliftIO
, orElseSTM
, module Data.Mutable
, 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
, primToPrim
, primToIO
, primToST
, module Data.Primitive.MutVar
, trace
, traceShow
, traceId
, traceM
, traceShowId
, traceShowM
, module Data.Time
, Generic
, Identity (..)
, MonadReader
, ask
, asks
, ReaderT (..)
, Reader
, module Data.Foldable
, module Data.Traversable
, module Data.Bifunctor
, module Data.MonoTraversable
, module Data.MonoTraversable.Unprefixed
, module Data.Sequences
, module Data.Containers
, module Data.Builder
, module Data.NonNull
, toByteVector
, fromByteVector
, module Say
, yieldThread
, waitAsync
, pollAsync
, waitCatchAsync
, linkAsync
, link2Async
, map
, 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
, (\\)
, intersect
, Show (..)
, tshow
, tlshow
, charToLower
, charToUpper
, readFile
, readFileUtf8
, writeFile
, writeFileUtf8
, hGetContents
, hPut
, hGetChunk
, print
, putChar
, putStr
, putStrLn
, getChar
, getLine
, getContents
, interact
, DList
, asDList
, applyDList
, module Control.DeepSeq
, 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
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
, parseTime
, parseTimeM
, getCurrentTime
, defaultTimeLocale
)
import qualified Data.Set as Set
import qualified Data.Map as Map
import qualified Data.HashSet as HashSet
import GHC.Generics (Generic)
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
#if MIN_VERSION_base(4,9,0)
import GHC.Stack (HasCallStack)
#endif
tshow :: Show a => a -> Text
tshow = fromList . Prelude.show
tlshow :: Show a => a -> LText
tlshow = fromList . Prelude.show
charToLower :: Char -> Char
charToLower = Char.toLower
charToUpper :: Char -> Char
charToUpper = Char.toUpper
readMay :: (Element c ~ Char, MonoFoldable c, Read a) => c -> Maybe a
readMay a =
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 \\
(\\) :: SetContainer a => a -> a -> a
(\\) = difference
{-# INLINE (\\) #-}
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
sortWith :: (Ord a, IsSequence c) => (Element c -> a) -> c -> c
sortWith f = sortBy $ comparing f
#if MIN_VERSION_base(4,9,0)
undefined :: HasCallStack => a
#else
undefined :: a
#endif
undefined = error "ClassyPrelude.undefined"
{-# DEPRECATED undefined "It is highly recommended that you either avoid partial functions or provide meaningful error messages" #-}
{-# 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
{-# WARNING traceId "Leaving traces in the code" #-}
traceId :: String -> String
traceId a = Trace.trace a a
{-# WARNING traceM "Leaving traces in the code" #-}
traceM :: (Monad m) => String -> m ()
traceM string = Trace.trace string $ return ()
{-# WARNING traceShowId "Leaving traces in the code" #-}
traceShowId :: (Show a) => a -> a
traceShowId a = Trace.trace (show a) a
{-# WARNING traceShowM "Leaving traces in the code" #-}
traceShowM :: (Show a, Monad m) => a -> m ()
traceShowM = traceM . show
yieldThread :: MonadIO m => m ()
yieldThread = liftIO Control.Concurrent.yield
{-# INLINE yieldThread #-}
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
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
ordNubBy :: (Ord b) => (a -> b) -> (a -> a -> Bool) -> [a] -> [a]
ordNubBy p f = go Map.empty
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
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
orElseSTM :: STM a -> STM a -> STM a
orElseSTM = STM.orElse
{-# INLINE orElseSTM #-}
whenM :: Monad m => m Bool -> m () -> m ()
whenM mbool action = mbool >>= flip when action
unlessM :: Monad m => m Bool -> m () -> m ()
unlessM mbool action = mbool >>= flip unless action
asDList :: DList a -> DList a
asDList = id
{-# INLINE asDList #-}
applyDList :: DList a -> [a] -> [a]
applyDList = DList.apply
{-# INLINE applyDList #-}
infixr 3 <&&>
(<&&>) :: Applicative a => a Bool -> a Bool -> a Bool
(<&&>) = liftA2 (&&)
{-# INLINE (<&&>) #-}
infixr 2 <||>
(<||>) :: Applicative a => a Bool -> a Bool -> a Bool
(<||>) = liftA2 (||)
{-# INLINE (<||>) #-}
toByteVector :: ByteString -> SVector Word8
toByteVector (PS fptr offset idx) = unsafeFromForeignPtr fptr offset idx
{-# INLINE toByteVector #-}
fromByteVector :: SVector Word8 -> ByteString
fromByteVector v =
PS fptr offset idx
where
(fptr, offset, idx) = unsafeToForeignPtr v
{-# INLINE fromByteVector #-}
waitAsync :: MonadIO m => Async a -> m a
waitAsync = atomically . waitSTM
pollAsync :: MonadIO m => Async a -> m (Maybe (Either SomeException a))
pollAsync = atomically . pollSTM
waitCatchAsync :: MonadIO m => Async a -> m (Either SomeException a)
waitCatchAsync = waitCatch
linkAsync :: MonadIO m => Async a -> m ()
linkAsync = UnliftIO.link
link2Async :: MonadIO m => Async a -> Async b -> m ()
link2Async a = UnliftIO.link2 a
readFile :: MonadIO m => FilePath -> m ByteString
readFile = liftIO . Data.ByteString.readFile
readFileUtf8 :: MonadIO m => FilePath -> m Text
readFileUtf8 = liftM decodeUtf8 . readFile
writeFile :: MonadIO m => FilePath -> ByteString -> m ()
writeFile fp = liftIO . Data.ByteString.writeFile fp
writeFileUtf8 :: MonadIO m => FilePath -> Text -> m ()
writeFileUtf8 fp = writeFile fp . encodeUtf8
hGetContents :: MonadIO m => Handle -> m ByteString
hGetContents = liftIO . Data.ByteString.hGetContents
hPut :: MonadIO m => Handle -> ByteString -> m ()
hPut h = liftIO . Data.ByteString.hPut h
hGetChunk :: MonadIO m => Handle -> m ByteString
hGetChunk = liftIO . flip Data.ByteString.hGetSome defaultChunkSize
putChar :: MonadIO m => Char -> m ()
putChar = liftIO . Prelude.putChar
putStr :: MonadIO m => Text -> m ()
putStr = liftIO . TextIO.putStr
putStrLn :: MonadIO m => Text -> m ()
putStrLn = liftIO . TextIO.putStrLn
getChar :: MonadIO m => m Char
getChar = liftIO Prelude.getChar
getLine :: MonadIO m => m Text
getLine = liftIO TextIO.getLine
getContents :: MonadIO m => m LText
getContents = liftIO LTextIO.getContents
interact :: MonadIO m => (LText -> LText) -> m ()
interact = liftIO . LTextIO.interact