module Mit.Prelude
  ( module Mit.Prelude,
    module X,
  )
where

import Control.Applicative as X ((<|>))
import Control.Category as X hiding (id, (.))
import Control.Concurrent.STM as X (atomically)
import Control.Exception as X hiding (handle, throw)
import Control.Monad as X hiding (return)
import Control.Monad.IO.Class as X (MonadIO (..))
import Data.Char as X
import Data.Foldable as X
import Data.Function as X
import Data.Functor as X (($>))
import Data.IORef as X
import Data.List.NonEmpty qualified as List1
import Data.Map as X (Map)
import Data.Maybe as X
import Data.Sequence as X (Seq)
import Data.Set as X (Set)
import Data.Text as X (Text)
import Data.Text qualified as Text
import Data.Text.IO qualified as Text
import Data.Traversable as X
import Data.Void as X (Void)
import Data.Word as X (Word64)
import GHC.Stack as X (HasCallStack)
import Mit.Seq1 as X (Seq1)
import Text.Read as X (readMaybe)
import Prelude as X hiding (head, id, return)

type List1 =
  List1.NonEmpty

(<&>) :: Functor f => f a -> (a -> b) -> f b
<&> :: forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
(<&>) =
  forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap

bug :: Text -> a
bug :: forall a. Text -> a
bug =
  forall a. HasCallStack => [Char] -> a
error forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
Text.unpack

-- FIXME make this faster
word642text :: Word64 -> Text
word642text :: Word64 -> Text
word642text =
  [Char] -> Text
Text.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show

putLines :: [Text] -> IO ()
putLines :: [Text] -> IO ()
putLines =
  Text -> IO ()
Text.putStr forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Text
Text.unlines

quoteText :: Text -> Text
quoteText :: Text -> Text
quoteText Text
s =
  if (Char -> Bool) -> Text -> Bool
Text.any Char -> Bool
isSpace Text
s then Text
"'" forall a. Semigroup a => a -> a -> a
<> HasCallStack => Text -> Text -> Text -> Text
Text.replace Text
"'" Text
"\\'" Text
s forall a. Semigroup a => a -> a -> a
<> Text
"'" else Text
s

-- FIXME make this faster
text2word64 :: Text -> Maybe Word64
text2word64 :: Text -> Maybe Word64
text2word64 =
  forall a. Read a => [Char] -> Maybe a
readMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
Text.unpack

onLeftM :: Monad m => (a -> m b) -> m (Either a b) -> m b
onLeftM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> m (Either a b) -> m b
onLeftM a -> m b
mx m (Either a b)
my =
  m (Either a b)
my forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> m b
mx forall (f :: * -> *) a. Applicative f => a -> f a
pure

onNothingM :: Monad m => m a -> m (Maybe a) -> m a
onNothingM :: forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
onNothingM m a
mx m (Maybe a)
my =
  m (Maybe a)
my forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe m a
mx forall (f :: * -> *) a. Applicative f => a -> f a
pure

unlessM :: Monad m => m Bool -> m () -> m ()
unlessM :: forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
unlessM m Bool
mx m ()
action =
  m Bool
mx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Bool
False -> m ()
action
    Bool
True -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

whenJust :: Applicative m => Maybe a -> (a -> m ()) -> m ()
whenJust :: forall (m :: * -> *) a.
Applicative m =>
Maybe a -> (a -> m ()) -> m ()
whenJust =
  forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_

whenM :: Monad m => m Bool -> m () -> m ()
whenM :: forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM m Bool
mx m ()
action =
  m Bool
mx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Bool
False -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    Bool
True -> m ()
action

whenNotM :: Monad m => m Bool -> m () -> m ()
whenNotM :: forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenNotM m Bool
mx =
  forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (Bool -> Bool
not forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Bool
mx)