packages feed

ron-0.13: lib/RON/Prelude.hs

{-# LANGUAGE ExplicitNamespaces #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE LambdaCase #-}

module RON.Prelude (
    module X,
    ByteStringL,
    fmapL,
    foldr1,
    headMay,
    lastDef,
    lastMay,
    maximumDef,
    maximumMay,
    maximumMayOn,
    maxOn,
    minimumDef,
    minimumMay,
    minimumMayOn,
    minOn,
    note,
    replicateM2,
    replicateM3,
    show,
    whenJust,
    (!!),
    (?:),
) where

-- TODO import           RON.Prelude.Writer as X
import Control.Monad.Writer.Strict as X (WriterT, runWriterT, tell)

-- base
import Control.Applicative as X (
    Alternative,
    Applicative,
    liftA2,
    many,
    optional,
    pure,
    some,
    (*>),
    (<*),
    (<*>),
    (<|>),
 )
import Control.Arrow as X ((>>>))
import Control.Exception as X (Exception)
import Control.Monad as X (
    Monad,
    filterM,
    guard,
    unless,
    void,
    when,
    (<=<),
    (=<<),
    (>=>),
    (>>),
    (>>=),
 )
import Control.Monad.Except as X (
    ExceptT (ExceptT),
    MonadError,
    catchError,
    liftEither,
    runExceptT,
    throwError,
 )
import Control.Monad.Fail as X (MonadFail, fail)
import Control.Monad.IO.Class as X (MonadIO, liftIO)
import Control.Monad.Reader as X (
    MonadReader,
    ReaderT (ReaderT),
    ask,
    asks,
    reader,
    runReaderT,
 )
import Control.Monad.State.Strict as X (
    MonadState,
    State,
    StateT,
    evalState,
    evalStateT,
    execStateT,
    get,
    gets,
    modify',
    put,
    runState,
    runStateT,
 )
import Control.Monad.Trans as X (MonadTrans, lift)
import Data.Bifunctor as X (bimap)
import Data.Bool as X (Bool (False, True), not, otherwise, (&&), (||))
import Data.ByteString as X (ByteString)
import Data.Char as X (Char, chr, ord, toLower, toUpper)
import Data.Coerce as X (Coercible, coerce)
import Data.Data as X (Data)
import Data.Either as X (Either (Left, Right), either)
import Data.Eq as X (Eq, (/=), (==))
import Data.Foldable as X (
    Foldable,
    all,
    and,
    any,
    asum,
    elem,
    fold,
    foldMap,
    foldl',
    foldr,
    for_,
    length,
    notElem,
    null,
    or,
    toList,
    traverse_,
 )
import Data.Function as X (const, flip, id, on, ($), (&), (.))
import Data.Functor as X (Functor, fmap, ($>), (<$), (<$>), (<&>))
import Data.Functor.Identity as X (Identity)
import Data.HashMap.Strict as X (HashMap)
import Data.Hashable as X (Hashable, hash)
import Data.IORef as X (IORef)
import Data.Int as X (Int, Int16, Int32, Int64, Int8)
import Data.List as X (
    drop,
    filter,
    genericLength,
    intercalate,
    isPrefixOf,
    isSuffixOf,
    lookup,
    map,
    partition,
    repeat,
    replicate,
    reverse,
    sort,
    sortBy,
    sortOn,
    span,
    splitAt,
    take,
    takeWhile,
    unlines,
    unwords,
    zip,
    zip3,
    zipWith,
    (++),
 )
import Data.List.NonEmpty as X (NonEmpty ((:|)), nonEmpty)
import Data.Map.Strict as X (Map)
import Data.Maybe as X (
    Maybe (Just, Nothing),
    catMaybes,
    fromMaybe,
    listToMaybe,
    mapMaybe,
    maybe,
    maybeToList,
 )
import Data.Monoid as X (Last (Last), Monoid, mempty)
import Data.Ord as X (
    Down (Down),
    Ord,
    Ordering (EQ, GT, LT),
    compare,
    comparing,
    max,
    min,
    (<),
    (<=),
    (>),
    (>=),
 )
import Data.Proxy as X (Proxy (Proxy))
import Data.Ratio as X ((%))
import Data.Semigroup as X (Semigroup, sconcat, (<>))
import Data.Sequence as X (Seq)
import Data.Set as X (Set)
import Data.String as X (String)
import Data.Text as X (Text)
import Data.Time as X (UTCTime)
import Data.Traversable as X (for, sequence, sequenceA, traverse)
import Data.Tuple as X (fst, snd, uncurry)
import Data.Type.Equality as X (type (~))
import Data.Typeable as X (Typeable)
import Data.Vector as X (Vector)
import Data.Word as X (Word, Word16, Word32, Word64, Word8)
import GHC.Enum as X (
    Bounded,
    Enum,
    fromEnum,
    maxBound,
    minBound,
    pred,
    succ,
    toEnum,
 )
import GHC.Err as X (error, undefined)
import GHC.Exts as X (Double)
import GHC.Generics as X (Generic)
import GHC.Integer as X (Integer)
import GHC.Num as X (Num, negate, subtract, (*), (+), (-))
import GHC.Real as X (
    Integral,
    fromIntegral,
    mod,
    realToFrac,
    round,
    (/),
    (^),
    (^^),
 )
import GHC.Stack as X (HasCallStack)
import System.IO as X (FilePath, IO)
import Text.Read as X (readMaybe)
import Text.Show as X (Show)

--------------------------------------------------------------------------------

import Data.ByteString.Lazy qualified as BSL
import Data.Foldable qualified
import Data.List (last, maximum, maximumBy, minimum, minimumBy)
import Data.String (IsString, fromString)
import Text.Show qualified

type ByteStringL = BSL.ByteString

fmapL :: (a -> b) -> Either a c -> Either b c
fmapL f = either (Left . f) Right

foldr1 :: (a -> a -> a) -> NonEmpty a -> a
foldr1 = Data.Foldable.foldr1

headMay :: [a] -> Maybe a
headMay = \case
    [] -> Nothing
    a : _ -> Just a

lastMay :: [a] -> Maybe a
lastMay = \case
    [] -> Nothing
    x : xs -> Just $ lastMayImpl x xs

lastMayImpl :: a -> [a] -> a
lastMayImpl x = \case
    [] -> x
    y : ys -> lastMayImpl y ys

lastDef :: a -> [a] -> a
lastDef def = list' def last

list' :: b -> ([a] -> b) -> [a] -> b
list' onEmpty onNonEmpty = \case
    [] -> onEmpty
    xs -> onNonEmpty xs

maximumDef :: (Ord a) => a -> [a] -> a
maximumDef def = list' def maximum

maximumMay :: (Ord a) => [a] -> Maybe a
maximumMay = list' Nothing (Just . maximum)

maximumMayOn :: (Ord b) => (a -> b) -> [a] -> Maybe a
maximumMayOn key = list' Nothing (Just . maximumBy (comparing key))

maxOn :: (Ord b) => (a -> b) -> a -> a -> a
maxOn f x y = if f x < f y then y else x

minimumDef :: (Ord a) => a -> [a] -> a
minimumDef def = list' def minimum

minimumMay :: (Ord a) => [a] -> Maybe a
minimumMay = list' Nothing (Just . minimum)

minimumMayOn :: (Ord b) => (a -> b) -> [a] -> Maybe a
minimumMayOn key = list' Nothing (Just . minimumBy (comparing key))

minOn :: (Ord b) => (a -> b) -> a -> a -> a
minOn f x y = if f x < f y then x else y

note :: e -> Maybe a -> Either e a
note e = maybe (Left e) Right

replicateM2 :: (Applicative m) => m a -> m (a, a)
replicateM2 ma = (,) <$> ma <*> ma

replicateM3 :: (Applicative m) => m a -> m (a, a, a)
replicateM3 ma = (,,) <$> ma <*> ma <*> ma

show :: (IsString s, Show a) => a -> s
show = fromString . Text.Show.show

whenJust :: (Applicative m) => Maybe a -> (a -> m ()) -> m ()
whenJust m f = maybe (pure ()) f m

(!!) :: [a] -> Int -> Maybe a
xs !! i
    | i < 0 = Nothing
    | otherwise = headMay $ drop i xs

-- | An infix form of 'fromMaybe' with arguments flipped.
(?:) :: Maybe a -> a -> a
maybeA ?: b = fromMaybe b maybeA
{-# INLINEABLE (?:) #-}

infixr 0 ?: