sprinkles-0.6.0.0: src/Web/Sprinkles/Prelude.hs
{-#LANGUAGE MultiParamTypeClasses #-}
{-#LANGUAGE FlexibleInstances #-}
{-#LANGUAGE FlexibleContexts #-}
{-#LANGUAGE RankNTypes #-}
{-#LANGUAGE FunctionalDependencies #-}
{-#LANGUAGE OverloadedStrings #-}
module Web.Sprinkles.Prelude
( module P
, LText
, LByteString
, Packable (..)
, MapLike (..)
, SetLike (..)
, TextLike (..)
, ListLike (..)
, StrictnessConvert (..)
, Encode (..)
, splitElem
, readMay
, Cased (..)
, throwM
, FileIO (..)
, hPut
, (++)
, concat
, empty
, getArgs
, getEnv
, lookupEnv
, sha1, sha256, sha512
)
where
import Prelude as P hiding ( unwords
, words
, lookup
, length
, take
, drop
, takeWhile
, dropWhile
, null
, tail
, break
, filter
, unlines
, putStr
, putStrLn
, hPutStr
, hPutStrLn
, readFile
, writeFile
, getContents
, hGetContents
, (++)
, concat
, empty
, sha1
)
import Data.Text as P (Text)
import Data.ByteString as P (ByteString)
import Data.Hashable (Hashable)
import Data.Map as P (Map)
import Data.HashMap.Strict as P (HashMap)
import Data.Set as P (Set)
import Data.HashSet as P (HashSet)
import Data.Hashable as P (Hashable (..))
import Data.Maybe as P (fromMaybe, catMaybes, isNothing, isJust)
import Data.String as P (IsString (..))
import Data.Vector as P (Vector)
import Data.List as P (sortOn)
import Data.Word as P (Word8, Word16, Word32, Word64, Word)
import Data.Int as P (Int8, Int16, Int32, Int64)
import Control.Monad as P
import Data.Semigroup as P hiding (getAll, All)
import Data.Monoid as P hiding (getFirst, getLast, First, Last, getAll, All)
import Control.Monad.IO.Class as P
import Control.Exception as P (bracket, bracket_, throw, catch)
import Control.Applicative as P hiding (empty)
import Data.IORef as P
import Control.Concurrent as P
import Control.Concurrent.STM as P
import Control.Concurrent.Chan as P
import Control.Concurrent.MVar as P
import Control.Exception as P hiding (throw)
import Data.Time as P (UTCTime (..), getCurrentTime)
import GHC.Generics as P (Generic)
import System.IO as P (stdin, stdout, stderr, Handle)
import System.IO.Error as P
import System.FilePath as P
import Text.Printf as P (printf)
import Control.Monad.Identity as P
import qualified Prelude
import qualified Data.List as List
import qualified Data.List.Split as List (splitWhen, splitOn)
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.HashMap.Strict as HashMap
import qualified Data.HashSet as HashSet
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 as Text
import qualified Data.Text.IO as Text
import qualified Data.Text.Encoding as Text
import qualified Data.Char as Char (toLower, toUpper)
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString as BS
import qualified Data.Vector as Vector
import qualified System.IO
import qualified System.Environment as Env
import qualified Data.Digest.Pure.SHA as SHA
import Text.Read (readMaybe)
import Control.Exception (throw)
readMay :: (Read a, Packable t [Char]) => t -> Maybe a
readMay = readMaybe . unpack
throwM :: (Exception e, Monad m) => e -> m a
throwM = throw
type LText = LText.Text
type LByteString = LBS.ByteString
(++) :: Semigroup m => m -> m -> m
(++) = (<>)
concat :: Monoid m => [m] -> m
concat = mconcat
empty :: Monoid m => m
empty = mempty
class Packable t s | t -> s where
pack :: s -> t
unpack :: t -> s
instance Packable Text [Char] where
pack = Text.pack
unpack = Text.unpack
instance Packable LText [Char] where
pack = LText.pack
unpack = LText.unpack
instance Packable [a] [a] where
pack = id
unpack = id
class MapLike m k v | m -> k, m -> v where
mapFromList :: [(k,v)] -> m
mapToList :: m -> [(k,v)]
lookup :: k -> m -> Maybe v
insertMap :: k -> v -> m -> m
deleteMap :: k -> m -> m
keys :: m -> [k]
instance (Eq k, Hashable k) => MapLike (HashMap k v) k v where
mapFromList = HashMap.fromList
mapToList = HashMap.toList
lookup = HashMap.lookup
insertMap = HashMap.insert
deleteMap = HashMap.delete
keys = HashMap.keys
instance (Ord k) => MapLike (Map k v) k v where
mapFromList = Map.fromList
mapToList = Map.toList
lookup = Map.lookup
insertMap = Map.insert
deleteMap = Map.delete
keys = Map.keys
instance (Ord k, Eq k) => MapLike [(k, v)] k v where
mapFromList = id
mapToList = id
lookup = List.lookup
insertMap = \k v -> ((k,v):)
deleteMap = \k -> List.filter ((/= k) . fst)
keys = map fst
class SetLike l c | l -> c where
setFromList :: [c] -> l
instance Ord a => SetLike (Set a) a where
setFromList = Set.fromList
class ListLike l c | l -> c where
length :: l -> Int
take :: Int -> l -> l
drop :: Int -> l -> l
takeWhile :: (c -> Bool) -> l -> l
dropWhile :: (c -> Bool) -> l -> l
break :: (c -> Bool) -> l -> (l, l)
splitWhen :: (c -> Bool) -> l -> [l]
splitSeq :: Eq c => l -> l -> [l]
splitSeq = \sep lst ->
map fromList $ List.splitOn (toList sep) (toList lst)
toList :: l -> [c]
fromList :: [c] -> l
null :: l -> Bool
headMay :: l -> Maybe c
headMay = \xs -> case toList xs of
(x:_) -> Just x
_ -> Nothing
tail :: l -> l
tail = drop 1
intercalate :: l -> [l] -> l
filter :: (c -> Bool) -> l -> l
filter = \p -> fromList . List.filter p . toList
splitElem :: (Eq c, ListLike l c) => c -> l -> [l]
splitElem c = splitWhen (== c)
instance ListLike [a] a where
length = List.length
take = List.take
drop = List.drop
takeWhile = List.takeWhile
dropWhile = List.dropWhile
break = List.break
splitWhen = List.splitWhen
toList = id
fromList = id
null = List.null
intercalate = List.intercalate
filter = List.filter
instance ListLike (Vector a) a where
length = Vector.length
take = Vector.take
drop = Vector.drop
takeWhile = Vector.takeWhile
dropWhile = Vector.dropWhile
break = Vector.break
splitWhen = splitVectorWhen
toList = Vector.toList
fromList = Vector.fromList
null = Vector.null
intercalate = mintercalate
filter = Vector.filter
mintercalate :: Monoid m => m -> [m] -> m
mintercalate _ [] = mempty
mintercalate _ [x] = x
mintercalate sep (x:xs) = x <> sep <> mintercalate sep xs
splitVectorWhen :: (a -> Bool) -> Vector a -> [Vector a]
splitVectorWhen p v = case Vector.findIndex p v of
Nothing ->
[v]
Just index ->
let (current, remainder) = Vector.splitAt index v
in current : splitVectorWhen p remainder
instance ListLike Text Char where
length = Text.length
take = Text.take
drop = Text.drop
takeWhile = Text.takeWhile
dropWhile = Text.dropWhile
break = Text.break
splitWhen = Text.split
toList = Text.unpack
fromList = Text.pack
null = Text.null
intercalate = Text.intercalate
filter = Text.filter
instance ListLike LText Char where
length = fromIntegral . LText.length
take = LText.take . fromIntegral
drop = LText.drop . fromIntegral
takeWhile = LText.takeWhile
dropWhile = LText.dropWhile
break = LText.break
splitWhen = LText.split
toList = LText.unpack
fromList = LText.pack
null = LText.null
intercalate = LText.intercalate
filter = LText.filter
instance ListLike ByteString Word8 where
length = BS.length
take = BS.take
drop = BS.drop
takeWhile = BS.takeWhile
dropWhile = BS.dropWhile
break = BS.break
splitWhen = BS.splitWith
toList = BS.unpack
fromList = BS.pack
null = BS.null
intercalate = BS.intercalate
filter = BS.filter
instance ListLike LByteString Word8 where
length = fromIntegral . LBS.length
take = LBS.take . fromIntegral
drop = LBS.drop . fromIntegral
takeWhile = LBS.takeWhile
dropWhile = LBS.dropWhile
break = LBS.break
splitWhen = LBS.splitWith
toList = LBS.unpack
fromList = LBS.pack
null = LBS.null
intercalate = LBS.intercalate
filter = LBS.filter
class (Monoid t, Semigroup t, IsString t) => TextLike t where
unwords :: [t] -> t
words :: t -> [t]
isPrefixOf :: t -> t -> Bool
isSuffixOf :: t -> t -> Bool
tshow :: forall a. Show a => a -> t
unlines :: [t] -> t
unlines = mintercalate "\n"
instance TextLike [Char] where
unwords = Prelude.unwords
words = Prelude.words
isPrefixOf = List.isPrefixOf
isSuffixOf = List.isSuffixOf
tshow = show
instance TextLike Text where
unwords = Text.unwords
words = Text.words
isPrefixOf = Text.isPrefixOf
isSuffixOf = Text.isSuffixOf
tshow = pack . show
unlines = Text.unlines
instance TextLike LText where
unwords = LText.unwords
words = LText.words
isPrefixOf = LText.isPrefixOf
isSuffixOf = LText.isSuffixOf
tshow = pack . show
unlines = LText.unlines
class Encode decoded encoded | decoded -> encoded, encoded -> decoded where
encodeUtf8 :: decoded -> encoded
decodeUtf8 :: encoded -> decoded
instance Encode Text ByteString where
encodeUtf8 = Text.encodeUtf8
decodeUtf8 = Text.decodeUtf8
instance Encode LText LByteString where
encodeUtf8 = LText.encodeUtf8
decodeUtf8 = LText.decodeUtf8
class StrictnessConvert strict lazy | strict -> lazy, lazy -> strict where
toStrict :: lazy -> strict
fromStrict :: strict -> lazy
instance StrictnessConvert ByteString LByteString where
toStrict = LBS.toStrict
fromStrict = LBS.fromStrict
instance StrictnessConvert Text LText where
toStrict = LText.toStrict
fromStrict = LText.fromStrict
class Cased t where
toUpper :: t -> t
toLower :: t -> t
instance Cased Char where
toUpper = Char.toUpper
toLower = Char.toLower
instance (Functor f, Cased t) => Cased (f t) where
toUpper = fmap toUpper
toLower = fmap toLower
instance Cased Text where
toUpper = Text.toUpper
toLower = Text.toLower
class (Semigroup s, IsString s) => FileIO s where
getContents :: IO s
readFile :: FilePath -> IO s
writeFile :: FilePath -> s -> IO ()
hGetContents :: Handle -> IO s
putStr :: s -> IO ()
putStrLn :: s -> IO ()
putStrLn = putStr . (<> "\n")
hPutStr :: Handle -> s -> IO ()
hPutStrLn :: Handle -> s -> IO ()
hPutStrLn = \h -> hPutStr h . (<> "\n")
instance FileIO String where
getContents = System.IO.getContents
readFile = System.IO.readFile
writeFile = System.IO.writeFile
hGetContents = System.IO.hGetContents
putStr = System.IO.putStr
putStrLn = System.IO.putStrLn
hPutStr = System.IO.hPutStr
hPutStrLn = System.IO.hPutStrLn
instance FileIO Text where
getContents = Text.getContents
readFile = Text.readFile
writeFile = Text.writeFile
hGetContents = Text.hGetContents
putStr = Text.putStr
putStrLn = Text.putStrLn
hPutStr = Text.hPutStr
hPutStrLn = Text.hPutStrLn
instance FileIO LText where
getContents = LText.getContents
readFile = LText.readFile
writeFile = LText.writeFile
hGetContents = LText.hGetContents
putStr = LText.putStr
putStrLn = LText.putStrLn
hPutStr = LText.hPutStr
hPutStrLn = LText.hPutStrLn
instance FileIO ByteString where
getContents = BS.getContents
readFile = BS.readFile
writeFile = BS.writeFile
hGetContents = BS.hGetContents
putStr = BS.putStr
hPutStr = BS.hPutStr
instance FileIO LByteString where
getContents = LBS.getContents
readFile = LBS.readFile
writeFile = LBS.writeFile
hGetContents = LBS.hGetContents
putStr = LBS.putStr
hPutStr = LBS.hPutStr
hPut :: FileIO s => Handle -> s -> IO ()
hPut = hPutStr
getArgs :: (Packable t String) => IO [t]
getArgs = map pack <$> Env.getArgs
getEnv :: (Packable v String) => String -> IO v
getEnv = fmap pack . Env.getEnv
lookupEnv :: (Packable v String) => String -> IO (Maybe v)
lookupEnv = fmap (fmap pack) . Env.lookupEnv
class HashDigest a where
digest :: forall t. SHA.Digest t -> a
instance HashDigest String where
digest = SHA.showDigest
instance HashDigest Text where
digest = pack . digest
instance HashDigest LText where
digest = pack . digest
instance HashDigest LByteString where
digest = SHA.bytestringDigest
instance HashDigest ByteString where
digest = toStrict . digest
instance HashDigest Integer where
digest = SHA.integerDigest
sha1 :: HashDigest a => LByteString -> a
sha1 = digest . SHA.sha1
sha256 :: HashDigest a => LByteString -> a
sha256 = digest . SHA.sha1
sha512 :: HashDigest a => LByteString -> a
sha512 = digest . SHA.sha1