content: {-# OPTIONS_GHC -Wno-orphans #-}
  
  -- | Internal utilities and instances
  module CalamityCommands.Internal.Utils (
    -- whileMFinalIO
    -- , untilJustFinalIO
    whenJust,
    whenM,
    unlessM,
    lastMaybe,
    leftToMaybe,
    rightToMaybe,
    justToEither,
    mapLeft,
    (<<$>>),
    (<<*>>),
    (<.>),
  ) where
  
  -- import           CalamityCommands.Internal.RunIntoIO
  
  import Control.Applicative
  
  import Data.Semigroup (Last (..))
  
  -- import qualified Polysemy              as P
  
  -- -- | Like whileM, but stateful effects are not preserved to mitigate memory leaks
  -- --
  -- -- This means Polysemy.Error won't work to break the loop, etc.
  -- -- Instead, Error/Alternative will just result in the loop quitting.
  -- whileMFinalIO :: P.Member (P.Final IO) r => P.Sem r Bool -> P.Sem r ()
  -- whileMFinalIO action = do
  --   action' <- runSemToIO action
  --   P.embedFinal $ go action'
  --   where go action' = do
  --           r <- action'
  --           case r of
  --             Just True ->
  --               go action'
  --             _ ->
  --               pure ()
  
  -- -- | Like untilJust, but stateful effects are not preserved to mitigate memory leaks
  -- --
  -- -- This means Polysemy.Error won't work to break the loop, etc.
  -- -- Instead, Error/Alternative will just result in another loop.
  -- untilJustFinalIO :: P.Member (P.Final IO) r => P.Sem r (Maybe a) -> P.Sem r a
  -- untilJustFinalIO action = do
  --   action' <- runSemToIO action
  --   P.embedFinal $ go action'
  --   where go action' = do
  --           r <- action'
  --           case r of
  --             Just (Just a) ->
  --               pure a
  --             _ ->
  --               go action'
  
  whenJust :: (Applicative m) => Maybe a -> (a -> m ()) -> m ()
  whenJust = flip $ maybe (pure ())
  
  whenM :: (Monad m) => m Bool -> m () -> m ()
  whenM p m =
    p >>= \case
      True -> m
      False -> pure ()
  
  unlessM :: (Monad m) => m Bool -> m () -> m ()
  unlessM = whenM . (not <$>)
  
  lastMaybe :: Maybe a -> Maybe a -> Maybe a
  lastMaybe l r = getLast <$> fmap Last l <> fmap Last r
  
  mapLeft :: (a -> c) -> Either a b -> Either c b
  mapLeft f (Left e) = Left (f e)
  mapLeft _ (Right x) = Right x
  
  leftToMaybe :: Either e a -> Maybe e
  leftToMaybe (Left x) = Just x
  leftToMaybe _ = Nothing
  
  rightToMaybe :: Either e a -> Maybe a
  rightToMaybe (Right x) = Just x
  rightToMaybe _ = Nothing
  
  justToEither :: Maybe e -> Either e ()
  justToEither (Just x) = Left x
  justToEither _ = Right ()
  
  (<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
  (<<$>>) = fmap . fmap
  
  infixl 4 <<$>>
  
  (<<*>>) :: (Applicative f, Applicative g) => f (g (a -> b)) -> f (g a) -> f (g b)
  (<<*>>) = liftA2 (<*>)
  
  infixl 4 <<*>>
  
  (<.>) :: (Functor f) => (a -> b) -> (c -> f a) -> (c -> f b)
  (<.>) f g x = f <$> g x
  
  infixl 4 <.>
  