-- |This is the central module on which to build upon when constructing Preludes for Polysemy libraries.
-- It reexports most core effects.
module Incipit (
  module Incipit.Prelude,
  module Polysemy,
  module Polysemy.Async,
  module Polysemy.AtomicState,
  module Polysemy.Error,
  module Polysemy.Fail,
  module Polysemy.Input,
  module Polysemy.Output,
  module Polysemy.Reader,
  module Polysemy.Resource,
  module Polysemy.State,
  module Polysemy.Tagged,
  module Polysemy.Writer,
  module Incipit,
  send,
) where

import qualified Control.Exception as Base
import Control.Exception (SomeException)
import Polysemy
import Polysemy.Async
import Polysemy.AtomicState
import Polysemy.Error
import Polysemy.Fail
import Polysemy.Input
import Polysemy.Internal (send)
import Polysemy.Internal.Kind (Append)
import Polysemy.Output
import Polysemy.Reader
import Polysemy.Resource
import Polysemy.State
import Polysemy.Tagged
import Polysemy.Writer

import Incipit.Prelude

-- |Run an 'IO' via 'Embed' and catch all exceptions, returning 'Either'.
tryAny ::
  Member (Embed IO) r =>
  IO a ->
  Sem r (Either Text a)
tryAny :: IO a -> Sem r (Either Text a)
tryAny =
  forall (r :: [(* -> *) -> * -> *]) a.
Member (Embed IO) r =>
IO a -> Sem r a
forall (m :: * -> *) (r :: [(* -> *) -> * -> *]) a.
Member (Embed m) r =>
m a -> Sem r a
embed @IO (IO (Either Text a) -> Sem r (Either Text a))
-> (IO a -> IO (Either Text a)) -> IO a -> Sem r (Either Text a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Either SomeException a -> Either Text a)
-> IO (Either SomeException a) -> IO (Either Text a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((SomeException -> Text) -> Either SomeException a -> Either Text a
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first SomeException -> Text
forall b a. (Show a, IsString b) => a -> b
show) (IO (Either SomeException a) -> IO (Either Text a))
-> (IO a -> IO (Either SomeException a))
-> IO a
-> IO (Either Text a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
Exception SomeException =>
IO a -> IO (Either SomeException a)
forall e a. Exception e => IO a -> IO (Either e a)
Base.try @SomeException
{-# inline tryAny #-}

-- |Run an 'IO' via 'Embed' and catch all exceptions, returning 'Maybe'.
tryMaybe ::
  Member (Embed IO) r =>
  IO a ->
  Sem r (Maybe a)
tryMaybe :: IO a -> Sem r (Maybe a)
tryMaybe =
  forall (r :: [(* -> *) -> * -> *]) a.
Member (Embed IO) r =>
IO a -> Sem r a
forall (m :: * -> *) (r :: [(* -> *) -> * -> *]) a.
Member (Embed m) r =>
m a -> Sem r a
embed @IO (IO (Maybe a) -> Sem r (Maybe a))
-> (IO a -> IO (Maybe a)) -> IO a -> Sem r (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Either SomeException a -> Maybe a)
-> IO (Either SomeException a) -> IO (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either SomeException a -> Maybe a
forall l r. Either l r -> Maybe r
rightToMaybe (IO (Either SomeException a) -> IO (Maybe a))
-> (IO a -> IO (Either SomeException a)) -> IO a -> IO (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
Exception SomeException =>
IO a -> IO (Either SomeException a)
forall e a. Exception e => IO a -> IO (Either e a)
Base.try @SomeException
{-# inline tryMaybe #-}

-- |Run an 'IO' via 'Embed' and catch and ignore all exceptions.
ignoreException ::
  Member (Embed IO) r =>
  IO () ->
  Sem r ()
ignoreException :: IO () -> Sem r ()
ignoreException =
  Sem r (Either SomeException ()) -> Sem r ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Sem r (Either SomeException ()) -> Sem r ())
-> (IO () -> Sem r (Either SomeException ())) -> IO () -> Sem r ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r :: [(* -> *) -> * -> *]) a.
Member (Embed IO) r =>
IO a -> Sem r a
forall (m :: * -> *) (r :: [(* -> *) -> * -> *]) a.
Member (Embed m) r =>
m a -> Sem r a
embed @IO (IO (Either SomeException ()) -> Sem r (Either SomeException ()))
-> (IO () -> IO (Either SomeException ()))
-> IO ()
-> Sem r (Either SomeException ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
Exception SomeException =>
IO a -> IO (Either SomeException a)
forall e a. Exception e => IO a -> IO (Either e a)
Base.try @SomeException
{-# inline ignoreException #-}

-- |Convenience type alias for concatenating two effect rows.
type a ++ b =
  Append a b

infixr 5 ++