-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Composable Contravariant Comonadic Logging Library
--   
--   This package provides core types and functions to work with the
--   LogAction data type which is both simple and powerful.
--   
--   
--   newtype LogAction m msg = LogAction
--       { unLogAction :: msg -> m ()
--       }
--   
--   
--   The ideas behind this package are described in the following blog
--   post:
--   
--   
--   
- co-log: Composable Contravariant Combinatorial Comonadic
--   Configurable Convenient Logging
--   
--   
--   See the following packages for different implementations based on
--   co-log-core:
--   
--   
--   
- co-log: taggless final implementations.
--   
- co-log-polysemy: extensible effects implementation based on
--   polysemy.
--   
@package co-log-core
@version 0.3.2.5

-- | Implements core data types and combinators for logging actions.
module Colog.Core.Action

-- | Polymorphic and very general logging action type.
--   
--   
--   
- msg type variables is an input for logger. It can
--   be Text or custom logging messsage with different fields that
--   you want to format in future.
--   
- m type variable is for monadic action inside which
--   logging is happening. It can be either IO or some custom pure
--   monad.
--   
--   
--   Key design point here is that LogAction is:
--   
--   
--   
- Semigroup
--   
- Monoid
--   
- Contravariant
--   
- Divisible
--   
- Decidable
--   
- Comonad
--   
newtype LogAction (m :: Type -> Type) msg
LogAction :: (msg -> m ()) -> LogAction (m :: Type -> Type) msg
[unLogAction] :: LogAction (m :: Type -> Type) msg -> msg -> m ()

-- | Operator version of unLogAction. Note that because of the
--   types, something like:
--   
--   
--   action <& msg1 <& msg2
--   
--   
--   doesn't make sense. Instead you want:
--   
--   
--   action <& msg1 >> action <& msg2
--   
--   
--   In addition, because <& has higher precedence than the
--   other operators in this module, the following:
--   
--   
--   f >$< action <& msg
--   
--   
--   is equivalent to:
--   
--   
--   (f >$< action) <& msg
--   
(<&) :: LogAction m msg -> msg -> m ()
infix 5 <&

-- | A flipped version of <&.
--   
--   It shares the same precedence as <&, so make sure to
--   surround lower precedence operators in parentheses:
--   
--   
--   msg &> (f >$< action)
--   
(&>) :: msg -> LogAction m msg -> m ()
infix 5 &>

-- | Joins some Foldable of LogActions into single
--   LogAction using Semigroup instance for LogAction.
--   This is basically specialized version of fold function.
foldActions :: forall t (m :: Type -> Type) a. (Foldable t, Applicative m) => t (LogAction m a) -> LogAction m a

-- | Takes predicate and performs given logging action only if predicate
--   returns True on input logging message.
cfilter :: forall (m :: Type -> Type) msg. Applicative m => (msg -> Bool) -> LogAction m msg -> LogAction m msg

-- | Performs the given logging action only if satisfies the monadic
--   predicate. Let's say you want to only to see logs that happened on
--   weekends.
--   
--   
--   isWeekendM :: MessageWithTimestamp -> IO Bool
--   
--   
--   And use it with cfilterM like this
--   
--   
--   logMessageAction :: LogAction m MessageWithTimestamp
--   
--   logWeekendAction :: LogAction m MessageWithTimestamp
--   logWeekendAction = cfilterM isWeekendM logMessageAction
--   
cfilterM :: Monad m => (msg -> m Bool) -> LogAction m msg -> LogAction m msg

-- | This combinator is contramap from contravariant functor. It
--   is useful when you have something like
--   
--   
--   data LogRecord = LR
--       { lrName    :: LoggerName
--       , lrMessage :: Text
--       }
--   
--   
--   and you need to provide LogAction which consumes
--   LogRecord
--   
--   
--   logRecordAction :: LogAction m LogRecord
--   
--   
--   when you only have action that consumes Text
--   
--   
--   logTextAction :: LogAction m Text
--   
--   
--   With cmap you can do the following:
--   
--   
--   logRecordAction :: LogAction m LogRecord
--   logRecordAction = cmap lrMesssage logTextAction
--   
--   
--   This action will print only lrMessage from
--   LogRecord. But if you have formatting function like this:
--   
--   
--   formatLogRecord :: LogRecord -> Text
--   
--   
--   you can apply it instead of lrMessage to log formatted
--   LogRecord as Text.
cmap :: forall a b (m :: Type -> Type). (a -> b) -> LogAction m b -> LogAction m a

-- | Operator version of cmap.
--   
--   
--   >>> 1 &> (show >$< logStringStdout)
--   1
--   
(>$<) :: forall a b (m :: Type -> Type). (a -> b) -> LogAction m b -> LogAction m a
infixr 3 >$<

-- | cmap for convertions that may fail
cmapMaybe :: forall (m :: Type -> Type) a b. Applicative m => (a -> Maybe b) -> LogAction m b -> LogAction m a

-- | Similar to cmapMaybe but for convertions that may fail inside a
--   monadic context.
cmapMaybeM :: Monad m => (a -> m (Maybe b)) -> LogAction m b -> LogAction m a

-- | This combinator is >$ from contravariant functor. Replaces
--   all locations in the output with the same value. The default
--   definition is contramap . const, so this is a more efficient
--   version.
--   
--   
--   >>> "Hello?" &> ("OUT OF SERVICE" >$ logStringStdout)
--   OUT OF SERVICE
--   
--   >>> ("OUT OF SERVICE" >$ logStringStdout) <& 42
--   OUT OF SERVICE
--   
(>$) :: forall b (m :: Type -> Type) a. b -> LogAction m b -> LogAction m a
infixl 4 >$

-- | cmapM combinator is similar to cmap but allows to call
--   monadic functions (functions that require extra context) to extend
--   consumed value. Consider the following example.
--   
--   You have this logging record:
--   
--   
--   data LogRecord = LR
--       { lrTime    :: UTCTime
--       , lrMessage :: Text
--       }
--   
--   
--   and you also have logging consumer inside IO for such record:
--   
--   
--   logRecordAction :: LogAction IO LogRecord
--   
--   
--   But you need to return consumer only for Text messages:
--   
--   
--   logTextAction :: LogAction IO Text
--   
--   
--   If you have function that can extend Text to LogRecord
--   like the function below:
--   
--   
--   withTime :: Text -> IO LogRecord
--   withTime msg = do
--       time <- getCurrentTime
--       pure (LR time msg)
--   
--   
--   you can achieve desired behavior with cmapM in the following
--   way:
--   
--   
--   logTextAction :: LogAction IO Text
--   logTextAction = cmapM withTime myAction
--   
cmapM :: Monad m => (a -> m b) -> LogAction m b -> LogAction m a

-- | divide combinator from Divisible type class.
--   
--   
--   >>> logInt = LogAction print
--   
--   >>> "ABC" &> divide (\s -> (s, length s)) logStringStdout logInt
--   ABC
--   3
--   
divide :: forall (m :: Type -> Type) a b c. Applicative m => (a -> (b, c)) -> LogAction m b -> LogAction m c -> LogAction m a

-- | Monadic version of divide.
divideM :: Monad m => (a -> m (b, c)) -> LogAction m b -> LogAction m c -> LogAction m a

-- | conquer combinator from Divisible type class.
--   
--   Concretely, this is a LogAction that does nothing:
--   
--   
--   >>> conquer <& "hello?"
--   
--   >>> "hello?" &> conquer
--   
conquer :: forall (m :: Type -> Type) a. Applicative m => LogAction m a

-- | Operator version of divide id.
--   
--   
--   >>> logInt = LogAction print
--   
--   >>> (logStringStdout >*< logInt) <& ("foo", 1)
--   foo
--   1
--   
--   >>> (logInt >*< logStringStdout) <& (1, "foo")
--   1
--   foo
--   
(>*<) :: forall (m :: Type -> Type) a b. Applicative m => LogAction m a -> LogAction m b -> LogAction m (a, b)
infixr 4 >*<

-- | Perform a constant log action after another.
--   
--   
--   >>> logHello = LogAction (const (putStrLn "Hello!"))
--   
--   >>> "Greetings!" &> (logStringStdout >* logHello)
--   Greetings!
--   Hello!
--   
(>*) :: forall (m :: Type -> Type) a. Applicative m => LogAction m a -> LogAction m () -> LogAction m a
infixr 4 >*

-- | A flipped version of >*
(*<) :: forall (m :: Type -> Type) a. Applicative m => LogAction m () -> LogAction m a -> LogAction m a
infixr 4 *<

-- | lose combinator from Decidable type class.
lose :: forall a (m :: Type -> Type). (a -> Void) -> LogAction m a

-- | choose combinator from Decidable type class.
--   
--   
--   >>> logInt = LogAction print
--   
--   >>> f = choose (\a -> if a < 0 then Left "Negative" else Right a)
--   
--   >>> f logStringStdout logInt <& 1
--   1
--   
--   >>> f logStringStdout logInt <& (-1)
--   Negative
--   
choose :: forall a b c (m :: Type -> Type). (a -> Either b c) -> LogAction m b -> LogAction m c -> LogAction m a

-- | Monadic version of choose.
chooseM :: Monad m => (a -> m (Either b c)) -> LogAction m b -> LogAction m c -> LogAction m a

-- | Operator version of choose id.
--   
--   
--   >>> dontPrintInt = LogAction (const (putStrLn "Not printing Int"))
--   
--   >>> Left 1 &> (dontPrintInt >|< logStringStdout)
--   Not printing Int
--   
--   >>> (dontPrintInt >|< logStringStdout) <& Right ":)"
--   :)
--   
(>|<) :: forall (m :: Type -> Type) a b. LogAction m a -> LogAction m b -> LogAction m (Either a b)
infixr 3 >|<

-- | If msg is Monoid then extract performs given
--   log action by passing mempty to it.
--   
--   
--   >>> logPrint :: LogAction IO [Int]; logPrint = LogAction print
--   
--   >>> extract logPrint
--   []
--   
extract :: Monoid msg => LogAction m msg -> m ()

-- | This is a comonadic extend. It allows you to chain different
--   transformations on messages.
--   
--   
--   >>> f (LogAction l) = l ".f1" *> l ".f2"
--   
--   >>> g (LogAction l) = l ".g"
--   
--   >>> logStringStdout <& "foo"
--   foo
--   
--   >>> extend f logStringStdout <& "foo"
--   foo.f1
--   foo.f2
--   
--   >>> (extend g $ extend f logStringStdout) <& "foo"
--   foo.g.f1
--   foo.g.f2
--   
--   >>> (logStringStdout =>> f =>> g) <& "foo"
--   foo.g.f1
--   foo.g.f2
--   
extend :: Semigroup msg => (LogAction m msg -> m ()) -> LogAction m msg -> LogAction m msg

-- | extend with the arguments swapped. Dual to >>= for
--   a Monad.
(=>>) :: Semigroup msg => LogAction m msg -> (LogAction m msg -> m ()) -> LogAction m msg
infixl 1 =>>

-- | extend in operator form.
(<<=) :: Semigroup msg => (LogAction m msg -> m ()) -> LogAction m msg -> LogAction m msg
infixr 1 <<=

-- | Converts any LogAction that can log single message to the
--   LogAction that can log two messages. The new LogAction
--   behaves in the following way:
--   
--   
--   
- Joins two messages of type msg using <>
--   operator from Semigroup.
--   
- Passes resulted message to the given LogAction.
--   
--   
--   
--   >>> :{
--   let logger :: LogAction IO [Int]
--       logger = logPrint
--   in duplicate logger <& ([3, 4], [42, 10])
--   :}
--   [3,4,42,10]
--   
--   
--   Implementation note:
--   
--   True and fair translation of the duplicate function from the
--   Comonad interface should result in the LogAction of the
--   following form:
--   
--   
--   msg -> msg -> m ()
--   
--   
--   In order to capture this behavior, duplicate should have the
--   following type:
--   
--   
--   duplicate :: Semigroup msg => LogAction m msg -> LogAction (Compose ((->) msg) m) msg
--   
--   
--   However, it's quite awkward to work with such type. It's a known fact
--   that the following two types are isomorphic (see functions
--   curry and uncurry):
--   
--   
--   a -> b -> c
--   (a, b) -> c
--   
--   
--   So using this fact we can come up with the simpler interface.
duplicate :: forall msg (m :: Type -> Type). Semigroup msg => LogAction m msg -> LogAction m (msg, msg)

-- | Like duplicate but why stop on a pair of two messages if you
--   can log any Foldable of messages?
--   
--   
--   >>> :{
--   let logger :: LogAction IO [Int]
--       logger = logPrint
--   in multiplicate logger <& replicate 5 [1..3]
--   :}
--   [1,2,3,1,2,3,1,2,3,1,2,3,1,2,3]
--   
multiplicate :: forall f msg (m :: Type -> Type). (Foldable f, Monoid msg) => LogAction m msg -> LogAction m (f msg)

-- | Like multiplicate but instead of logging a batch of messages it
--   logs each of them separately.
--   
--   
--   >>> :{
--   let logger :: LogAction IO Int
--       logger = logPrint
--   in separate logger <& [1..5]
--   :}
--   1
--   2
--   3
--   4
--   5
--   
separate :: forall f msg (m :: Type -> Type). (Traversable f, Applicative m) => LogAction m msg -> LogAction m (f msg)

-- | Allows changing the internal monadic action.
--   
--   Let's say we have a pure logger action using PureLogger and
--   we want to log all messages into IO instead.
--   
--   If we provide the following function:
--   
--   
--   performPureLogsInIO :: PureLogger a -> IO a
--   
--   
--   then we can convert a logger action that uses a pure monad to a one
--   that performs the logging in the IO monad using:
--   
--   
--   hoistLogAction performPureLogsInIO :: LogAction (PureLogger a) a -> LogAction IO a
--   
hoistLogAction :: (forall x. () => m x -> n x) -> LogAction m a -> LogAction n a
instance Data.Functor.Contravariant.Contravariant (Colog.Core.Action.LogAction m)
instance Colog.Core.Action.UnrepresentableClass => GHC.Internal.Base.Functor (Colog.Core.Action.LogAction m)
instance GHC.Internal.Base.Applicative m => GHC.Internal.Base.Monoid (Colog.Core.Action.LogAction m a)
instance GHC.Internal.Base.Applicative m => GHC.Internal.Base.Semigroup (Colog.Core.Action.LogAction m a)

-- | Provides type class for values that has access to LogAction.
module Colog.Core.Class

-- | This types class contains simple pair of getter-setter and related
--   functions. It also provides the useful lens logActionL with the
--   default implementation using type class methods. The default one could
--   be easily overritten under your instances.
--   
--   Every instance of the this typeclass should satisfy the following
--   laws:
--   
--   
--   
- Set-Get: getLogAction (setLogAction l
--   env) ≡ l
--   
- Get-Set: setLogAction (getLogAction env)
--   env ≡ env
--   
- Set-Set: setLogAction l2 (setLogAction l1
--   env) ≡ setLogAction l2 env
--   
- Set-Over: overLogAction f env ≡
--   setLogAction (f $ getLogAction env) env
--   
class HasLog env msg (m :: Type -> Type)

-- | Extracts LogAction from the environment.
getLogAction :: HasLog env msg m => env -> LogAction m msg

-- | Sets LogAction to the given one inside the environment.
setLogAction :: HasLog env msg m => LogAction m msg -> env -> env

-- | Applies function to the LogAction inside the environment.
overLogAction :: HasLog env msg m => (LogAction m msg -> LogAction m msg) -> env -> env

-- | Lens for LogAction inside the environment.
logActionL :: HasLog env msg m => Lens' env (LogAction m msg)

-- | The monomorphic lenses which don't change the type of the container
--   (or of the value inside).
type Lens' s a = forall (f :: Type -> Type). Functor f => a -> f a -> s -> f s
instance Colog.Core.Class.HasLog (Colog.Core.Action.LogAction m msg) msg m

-- | Introduces logging actions working in MonadIO. These actions
--   are very basic and inefficient because they use the String data
--   type. If you don't want to have extra dependencies and performance of
--   logging is not the bottleneck of your application, then these
--   functions should be enough. Otherwise use functions from the
--   Colog.Actions module from the co-log package.
module Colog.Core.IO

-- | Action that prints String to stdout. This action does not flush
--   the output buffer. If buffering mode is block buffering, the effect of
--   this action can be delayed.
--   
--   
--   >>> logStringStdout <& "foo"
--   foo
--   
logStringStdout :: forall (m :: Type -> Type). MonadIO m => LogAction m String

-- | Action that prints String to stderr. This action does not flush
--   the output buffer. If buffering mode is block buffering, the effect of
--   this action can be delayed.
--   
--   
--   >>> logStringStderr <& "foo"
--   foo
--   
logStringStderr :: forall (m :: Type -> Type). MonadIO m => LogAction m String

-- | Action that prints String to Handle. This action does
--   not flush the output buffer. If buffering mode is block buffering, the
--   effect of this action can be delayed.
--   
--   
--   >>> logStringHandle stderr <& "foo"
--   foo
--   
logStringHandle :: forall (m :: Type -> Type). MonadIO m => Handle -> LogAction m String

-- | Action that prints String to file. Instead of returning
--   LogAction it's implemented in continuation-passing style
--   because it's more efficient to open file only once at the start of the
--   application and write to Handle instead of opening file each
--   time we need to write to it.
--   
--   Opens file in AppendMode. Automatically flushes the output
--   buffer.
--   
--   
--   >>> logger action = action <& "foo"
--   
--   >>> withLogStringFile "/dev/stdout" logger
--   foo
--   
withLogStringFile :: forall (m :: Type -> Type) r. MonadIO m => FilePath -> (LogAction m String -> IO r) -> IO r

-- | Action that prints to stdout using Show. This action does not
--   flush the output buffer. If buffering mode is block buffering, the
--   effect of this action can be delayed.
--   
--   
--   >>> logPrint <& 5
--   5
--   
logPrint :: forall a (m :: Type -> Type). (Show a, MonadIO m) => LogAction m a

-- | Action that prints to stderr using Show. This action does not
--   flush the output buffer. If buffering mode is block buffering, the
--   effect of this action can be delayed.
--   
--   
--   >>> logPrintStderr <& 5
--   5
--   
logPrintStderr :: forall a (m :: Type -> Type). (Show a, MonadIO m) => LogAction m a

-- | Action that prints to a Handle using Show. This action
--   does not flush the output buffer. If buffering mode is block
--   buffering, the effect of this action can be delayed.
--   
--   
--   >>> logPrintHandle stderr <& 5
--   5
--   
logPrintHandle :: forall a (m :: Type -> Type). (Show a, MonadIO m) => Handle -> LogAction m a

-- | Action that prints to a file using Show. See
--   withLogStringFile for details.
withLogPrintFile :: forall a (m :: Type -> Type) r. (Show a, MonadIO m) => FilePath -> (LogAction m a -> IO r) -> IO r

-- | Lifts a LogAction over IO into a more general Monad.
--   
--   
--   >>> logToStdout = LogAction putStrLn
--   
--   >>> liftLogIO logToStdout <& "foo"
--   foo
--   
liftLogIO :: forall (m :: Type -> Type) msg. MonadIO m => LogAction IO msg -> LogAction m msg

-- | This action can be used in combination with other actions to flush a
--   handle every time you log anything.
logFlush :: forall (m :: Type -> Type) a. MonadIO m => Handle -> LogAction m a

-- | This module introduces Severity data type for expressing how
--   severe the message is. Also, it contains useful functions and patterns
--   for work with Severity.
--   
--   TODO: table
module Colog.Core.Severity

-- | Severity for the log messages.
data Severity

-- | Information useful for debug purposes.
--   
--   E.g. output of the function that is important for the internal
--   development, not for users. Like, the result of SQL query.
Debug :: Severity

-- | Normal operational information.
--   
--   E.g. describing general steps: starting application, finished
--   downloading.
Info :: Severity

-- | General warnings, non-critical failures.
--   
--   E.g. couldn't download icon from some service to display.
Warning :: Severity

-- | General errors/severe errors.
--   
--   E.g. exceptional situations: couldn't syncronize accounts.
Error :: Severity
pattern D :: Severity
pattern I :: Severity
pattern W :: Severity
pattern E :: Severity

-- | Filters messages by the given Severity.
filterBySeverity :: forall (m :: Type -> Type) a. Applicative m => Severity -> (a -> Severity) -> LogAction m a -> LogAction m a

-- | A message tagged with a Severity.
--   
--   It is common to want to log various types of messages tagged with a
--   severity. WithSeverity provides a standard way to do so while
--   allowing the messages to be processed independently of the severity.
--   
--   It is easy to cmap over a 'LogAction m (WithSeverity a)', or
--   to filter based on the severity.
--   
--   
--   logSomething :: LogAction m (WithSeverity String) -> m ()
--   logSomething logger = logger <& "hello" `WithSeverity` Info
--   
--   cmap' :: (b -> a) -> LogAction m (WithSeverity a) -> LogAction m (WithSeverity b)
--   cmap' f action = cmap (fmap f) action
--   
--   filterBySeverity' :: (Applicative m) => Severity -> LogAction m (WithSeverity a) -> LogAction m (WithSeverity a)
--   filterBySeverity' threshold action = filterBySeverity threshold getSeverity action
--   
data WithSeverity msg
WithSeverity :: msg -> Severity -> WithSeverity msg
[getMsg] :: WithSeverity msg -> msg
[getSeverity] :: WithSeverity msg -> Severity

-- | Map the given function over the severity of a WithSeverity.
--   
--   This can be useful to operate generically over the severity, for
--   example:
--   
--   
--   suppressErrors :: LogAction m (WithSeverity msg) -> LogAction m (WithSeverity msg)
--   suppressErrors = cmap (mapSeverity (s -> if s == Error then Warning else s))
--   
mapSeverity :: (Severity -> Severity) -> WithSeverity msg -> WithSeverity msg
instance GHC.Internal.Enum.Bounded Colog.Core.Severity.Severity
instance GHC.Internal.Enum.Enum Colog.Core.Severity.Severity
instance GHC.Classes.Eq Colog.Core.Severity.Severity
instance GHC.Classes.Eq msg => GHC.Classes.Eq (Colog.Core.Severity.WithSeverity msg)
instance GHC.Internal.Data.Foldable.Foldable Colog.Core.Severity.WithSeverity
instance GHC.Internal.Base.Functor Colog.Core.Severity.WithSeverity
instance GHC.Internal.Ix.Ix Colog.Core.Severity.Severity
instance GHC.Classes.Ord Colog.Core.Severity.Severity
instance GHC.Classes.Ord msg => GHC.Classes.Ord (Colog.Core.Severity.WithSeverity msg)
instance GHC.Internal.Read.Read Colog.Core.Severity.Severity
instance GHC.Internal.Show.Show Colog.Core.Severity.Severity
instance GHC.Internal.Show.Show msg => GHC.Internal.Show.Show (Colog.Core.Severity.WithSeverity msg)
instance GHC.Internal.Data.Traversable.Traversable Colog.Core.Severity.WithSeverity

-- | Exports all core functionality. co-log-core is a lightweight
--   package that defines only core data type and various combinators to
--   work with it.
--   
--   Fundamentals of co-log-core are based on the following data
--   type:
--   
--   
--   newtype LogAction m msg = LogAction
--       { unLogAction :: msg -> m ()
--       }
--   
--   
--   This data type provides extremely composable and flexible interface by
--   having many instances of the standard algebraic data types.
--   
--   The package has the following structure:
--   
--   
--   
- Colog.Core.Action: definition of the main data type
--   and its combinators.
--   
- Colog.Core.Class: HasLog typeclass that
--   describes how different values (e.g. application environment) can
--   store and modify LogAction.
--   
- Colog.Core.IO: basic loggers that work with
--   MonadIO and String.
--   
- Colog.Core.Severity: logger severity.
--   
module Colog.Core
