{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Control.Tracer
( Tracer (..)
, traceWith
, arrow
, use
, Arrow.squelch
, Arrow.emit
, Arrow.effect
, nullTracer
, stdoutTracer
, debugTracer
, natTracer
, Arrow.nat
, traceMaybe
, squelchUnless
, Contravariant(..)
) where
import Control.Arrow (arr, runKleisli, (&&&), (|||))
import Control.Category ((>>>))
import qualified Control.Tracer.Arrow as Arrow
import Data.Functor.Contravariant (Contravariant (..))
import Debug.Trace (traceM)
newtype Tracer m a = Tracer { forall (m :: * -> *) a. Tracer m a -> TracerA m a ()
runTracer :: Arrow.TracerA m a () }
instance Monad m => Contravariant (Tracer m) where
contramap :: forall a' a. (a' -> a) -> Tracer m a -> Tracer m a'
contramap a' -> a
f Tracer m a
tracer = TracerA m a' () -> Tracer m a'
forall (m :: * -> *) a. TracerA m a () -> Tracer m a
Tracer ((a' -> a) -> TracerA m a' a
forall b c. (b -> c) -> TracerA m b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr a' -> a
f TracerA m a' a -> TracerA m a () -> TracerA m a' ()
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Tracer m a -> TracerA m a ()
forall (m :: * -> *) a. Tracer m a -> TracerA m a ()
use Tracer m a
tracer)
instance Monad m => Semigroup (Tracer m s) where
Tracer TracerA m s ()
a1 <> :: Tracer m s -> Tracer m s -> Tracer m s
<> Tracer TracerA m s ()
a2 = TracerA m s () -> Tracer m s
forall (m :: * -> *) a. TracerA m a () -> Tracer m a
Tracer (TracerA m s ()
a1 TracerA m s () -> TracerA m s () -> TracerA m s ((), ())
forall b c c'.
TracerA m b c -> TracerA m b c' -> TracerA m b (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& TracerA m s ()
a2 TracerA m s ((), ()) -> TracerA m ((), ()) () -> TracerA m s ()
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (((), ()) -> ()) -> TracerA m ((), ()) ()
forall b c. (b -> c) -> TracerA m b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr ((), ()) -> ()
discard)
where
discard :: ((), ()) -> ()
discard :: ((), ()) -> ()
discard = () -> ((), ()) -> ()
forall a b. a -> b -> a
const ()
instance Monad m => Monoid (Tracer m s) where
mappend :: Tracer m s -> Tracer m s -> Tracer m s
mappend = Tracer m s -> Tracer m s -> Tracer m s
forall a. Semigroup a => a -> a -> a
(<>)
mempty :: Tracer m s
mempty = Tracer m s
forall (m :: * -> *) s. Monad m => Tracer m s
nullTracer
{-# INLINE traceWith #-}
traceWith :: Monad m => Tracer m a -> a -> m ()
traceWith :: forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith (Tracer TracerA m a ()
tr) = Kleisli m a () -> a -> m ()
forall (m :: * -> *) a b. Kleisli m a b -> a -> m b
runKleisli (TracerA m a () -> Kleisli m a ()
forall (m :: * -> *) a. Monad m => TracerA m a () -> Kleisli m a ()
Arrow.runTracerA TracerA m a ()
tr)
{-# INLINE arrow #-}
arrow :: Arrow.TracerA m a () -> Tracer m a
arrow :: forall (m :: * -> *) a. TracerA m a () -> Tracer m a
arrow = TracerA m a () -> Tracer m a
forall (m :: * -> *) a. TracerA m a () -> Tracer m a
Tracer
{-# INLINE use #-}
use :: Tracer m a -> Arrow.TracerA m a ()
use :: forall (m :: * -> *) a. Tracer m a -> TracerA m a ()
use = Tracer m a -> TracerA m a ()
forall (m :: * -> *) a. Tracer m a -> TracerA m a ()
runTracer
{-# INLINE nullTracer #-}
nullTracer :: Monad m => Tracer m a
nullTracer :: forall (m :: * -> *) s. Monad m => Tracer m s
nullTracer = TracerA m a () -> Tracer m a
forall (m :: * -> *) a. TracerA m a () -> Tracer m a
Tracer TracerA m a ()
forall (m :: * -> *) a. Applicative m => TracerA m a ()
Arrow.squelch
{-# INLINE emit #-}
emit :: Applicative m => (a -> m ()) -> Tracer m a
emit :: forall (m :: * -> *) a. Applicative m => (a -> m ()) -> Tracer m a
emit a -> m ()
f = TracerA m a () -> Tracer m a
forall (m :: * -> *) a. TracerA m a () -> Tracer m a
Tracer ((a -> m ()) -> TracerA m a ()
forall (m :: * -> *) a.
Applicative m =>
(a -> m ()) -> TracerA m a ()
Arrow.emit a -> m ()
f)
traceMaybe :: Monad m => (a -> Maybe b) -> Tracer m b -> Tracer m a
traceMaybe :: forall (m :: * -> *) a b.
Monad m =>
(a -> Maybe b) -> Tracer m b -> Tracer m a
traceMaybe a -> Maybe b
k Tracer m b
tr = TracerA m a () -> Tracer m a
forall (m :: * -> *) a. TracerA m a () -> Tracer m a
Tracer (TracerA m a () -> Tracer m a) -> TracerA m a () -> Tracer m a
forall a b. (a -> b) -> a -> b
$ TracerA m a (Either () b)
classify TracerA m a (Either () b)
-> TracerA m (Either () b) () -> TracerA m a ()
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (TracerA m () ()
forall (m :: * -> *) a. Applicative m => TracerA m a ()
Arrow.squelch TracerA m () () -> TracerA m b () -> TracerA m (Either () b) ()
forall b d c.
TracerA m b d -> TracerA m c d -> TracerA m (Either b c) d
forall (a :: * -> * -> *) b d c.
ArrowChoice a =>
a b d -> a c d -> a (Either b c) d
||| Tracer m b -> TracerA m b ()
forall (m :: * -> *) a. Tracer m a -> TracerA m a ()
use Tracer m b
tr)
where
classify :: TracerA m a (Either () b)
classify = (a -> Either () b) -> TracerA m a (Either () b)
forall b c. (b -> c) -> TracerA m b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (Either () b -> (b -> Either () b) -> Maybe b -> Either () b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Either () b
forall a b. a -> Either a b
Left ()) b -> Either () b
forall a b. b -> Either a b
Right (Maybe b -> Either () b) -> (a -> Maybe b) -> a -> Either () b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe b
k)
squelchUnless :: Monad m => (a -> Bool) -> Tracer m a -> Tracer m a
squelchUnless :: forall (m :: * -> *) a.
Monad m =>
(a -> Bool) -> Tracer m a -> Tracer m a
squelchUnless a -> Bool
p = (a -> Maybe a) -> Tracer m a -> Tracer m a
forall (m :: * -> *) a b.
Monad m =>
(a -> Maybe b) -> Tracer m b -> Tracer m a
traceMaybe (\a
a -> if a -> Bool
p a
a then a -> Maybe a
forall a. a -> Maybe a
Just a
a else Maybe a
forall a. Maybe a
Nothing)
natTracer :: forall m n s . (forall x . m x -> n x) -> Tracer m s -> Tracer n s
natTracer :: forall (m :: * -> *) (n :: * -> *) s.
(forall x. m x -> n x) -> Tracer m s -> Tracer n s
natTracer forall x. m x -> n x
h (Tracer TracerA m s ()
tr) = TracerA n s () -> Tracer n s
forall (m :: * -> *) a. TracerA m a () -> Tracer m a
Tracer ((forall x. m x -> n x) -> TracerA m s () -> TracerA n s ()
forall (m :: * -> *) (n :: * -> *) a b.
(forall x. m x -> n x) -> TracerA m a b -> TracerA n a b
Arrow.nat m x -> n x
forall x. m x -> n x
h TracerA m s ()
tr)
stdoutTracer :: Tracer IO String
stdoutTracer :: Tracer IO String
stdoutTracer = (String -> IO ()) -> Tracer IO String
forall (m :: * -> *) a. Applicative m => (a -> m ()) -> Tracer m a
emit String -> IO ()
putStrLn
debugTracer :: Applicative m => Tracer m String
debugTracer :: forall (m :: * -> *). Applicative m => Tracer m String
debugTracer = (String -> m ()) -> Tracer m String
forall (m :: * -> *) a. Applicative m => (a -> m ()) -> Tracer m a
emit String -> m ()
forall (f :: * -> *). Applicative f => String -> f ()
traceM