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

import Control.Category as X hiding (id, (.))
import Control.Exception as X hiding (handle)
import Control.Monad as X
import Data.Char as X
import Data.Foldable as X
import Data.Function as X
import qualified Data.List.NonEmpty as List1
import Data.Maybe as X
import Data.Text as X (Text)
import qualified Data.Text as Text
import qualified Data.Text.IO as Text
import Data.Traversable as X
import System.IO (Handle, hIsEOF)
import Text.Read as X (readMaybe)
import Prelude as X hiding (head, id)

type List1 =
  List1.NonEmpty

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

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

drainTextHandle :: Handle -> IO [Text]
drainTextHandle :: Handle -> IO [Text]
drainTextHandle Handle
handle = do
  let loop :: [Text] -> IO [Text]
loop [Text]
acc =
        Handle -> IO Bool
hIsEOF Handle
handle IO Bool -> (Bool -> IO [Text]) -> IO [Text]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
          Bool
False -> do
            Text
line <- Handle -> IO Text
Text.hGetLine Handle
handle
            [Text] -> IO [Text]
loop (Text
line Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Text]
acc)
          Bool
True -> [Text] -> IO [Text]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Text] -> [Text]
forall a. [a] -> [a]
reverse [Text]
acc)
  [Text] -> IO [Text]
loop []

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

putLines :: [Text] -> IO ()
putLines :: [Text] -> IO ()
putLines =
  Text -> IO ()
Text.putStr (Text -> IO ()) -> ([Text] -> Text) -> [Text] -> IO ()
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
"'" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text -> Text
Text.replace Text
"'" Text
"\\'" Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"'" else Text
s

-- FIXME make this faster
text2int :: Text -> Maybe Integer
text2int :: Text -> Maybe Integer
text2int =
  [Char] -> Maybe Integer
forall a. Read a => [Char] -> Maybe a
readMaybe ([Char] -> Maybe Integer)
-> (Text -> [Char]) -> Text -> Maybe Integer
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 :: (a -> m b) -> m (Either a b) -> m b
onLeftM a -> m b
mx m (Either a b)
my =
  m (Either a b)
my m (Either a b) -> (Either a b -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> m b) -> (b -> m b) -> Either a b -> m b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> m b
mx b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure

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

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

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