module PlutusCore.Builtin.Emitter
    ( Emitter (..)
    , runEmitter
    , emit
    ) where

import Control.Monad.Trans.Writer.Strict (Writer, runWriter, tell)
import Data.DList as DList
import Data.Text (Text)

-- | A monad for logging.
newtype Emitter a = Emitter
    { Emitter a -> Writer (DList Text) a
unEmitter :: Writer (DList Text) a
    } deriving newtype (a -> Emitter b -> Emitter a
(a -> b) -> Emitter a -> Emitter b
(forall a b. (a -> b) -> Emitter a -> Emitter b)
-> (forall a b. a -> Emitter b -> Emitter a) -> Functor Emitter
forall a b. a -> Emitter b -> Emitter a
forall a b. (a -> b) -> Emitter a -> Emitter b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Emitter b -> Emitter a
$c<$ :: forall a b. a -> Emitter b -> Emitter a
fmap :: (a -> b) -> Emitter a -> Emitter b
$cfmap :: forall a b. (a -> b) -> Emitter a -> Emitter b
Functor, Functor Emitter
a -> Emitter a
Functor Emitter
-> (forall a. a -> Emitter a)
-> (forall a b. Emitter (a -> b) -> Emitter a -> Emitter b)
-> (forall a b c.
    (a -> b -> c) -> Emitter a -> Emitter b -> Emitter c)
-> (forall a b. Emitter a -> Emitter b -> Emitter b)
-> (forall a b. Emitter a -> Emitter b -> Emitter a)
-> Applicative Emitter
Emitter a -> Emitter b -> Emitter b
Emitter a -> Emitter b -> Emitter a
Emitter (a -> b) -> Emitter a -> Emitter b
(a -> b -> c) -> Emitter a -> Emitter b -> Emitter c
forall a. a -> Emitter a
forall a b. Emitter a -> Emitter b -> Emitter a
forall a b. Emitter a -> Emitter b -> Emitter b
forall a b. Emitter (a -> b) -> Emitter a -> Emitter b
forall a b c. (a -> b -> c) -> Emitter a -> Emitter b -> Emitter c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: Emitter a -> Emitter b -> Emitter a
$c<* :: forall a b. Emitter a -> Emitter b -> Emitter a
*> :: Emitter a -> Emitter b -> Emitter b
$c*> :: forall a b. Emitter a -> Emitter b -> Emitter b
liftA2 :: (a -> b -> c) -> Emitter a -> Emitter b -> Emitter c
$cliftA2 :: forall a b c. (a -> b -> c) -> Emitter a -> Emitter b -> Emitter c
<*> :: Emitter (a -> b) -> Emitter a -> Emitter b
$c<*> :: forall a b. Emitter (a -> b) -> Emitter a -> Emitter b
pure :: a -> Emitter a
$cpure :: forall a. a -> Emitter a
$cp1Applicative :: Functor Emitter
Applicative, Applicative Emitter
a -> Emitter a
Applicative Emitter
-> (forall a b. Emitter a -> (a -> Emitter b) -> Emitter b)
-> (forall a b. Emitter a -> Emitter b -> Emitter b)
-> (forall a. a -> Emitter a)
-> Monad Emitter
Emitter a -> (a -> Emitter b) -> Emitter b
Emitter a -> Emitter b -> Emitter b
forall a. a -> Emitter a
forall a b. Emitter a -> Emitter b -> Emitter b
forall a b. Emitter a -> (a -> Emitter b) -> Emitter b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> Emitter a
$creturn :: forall a. a -> Emitter a
>> :: Emitter a -> Emitter b -> Emitter b
$c>> :: forall a b. Emitter a -> Emitter b -> Emitter b
>>= :: Emitter a -> (a -> Emitter b) -> Emitter b
$c>>= :: forall a b. Emitter a -> (a -> Emitter b) -> Emitter b
$cp1Monad :: Applicative Emitter
Monad)

runEmitter :: Emitter a -> (a, DList Text)
runEmitter :: Emitter a -> (a, DList Text)
runEmitter = Writer (DList Text) a -> (a, DList Text)
forall w a. Writer w a -> (a, w)
runWriter (Writer (DList Text) a -> (a, DList Text))
-> (Emitter a -> Writer (DList Text) a)
-> Emitter a
-> (a, DList Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Emitter a -> Writer (DList Text) a
forall a. Emitter a -> Writer (DList Text) a
unEmitter
{-# INLINE runEmitter #-}

emit :: Text -> Emitter ()
emit :: Text -> Emitter ()
emit = Writer (DList Text) () -> Emitter ()
forall a. Writer (DList Text) a -> Emitter a
Emitter (Writer (DList Text) () -> Emitter ())
-> (Text -> Writer (DList Text) ()) -> Text -> Emitter ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList Text -> Writer (DList Text) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
tell (DList Text -> Writer (DList Text) ())
-> (Text -> DList Text) -> Text -> Writer (DList Text) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> DList Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE emit #-}