{-# LANGUAGE RankNTypes #-} module Plow.Throwing where import Data.Functor.Contravariant (Contravariant (..)) import Plow.Logging newtype Thrower m a = Thrower (forall b. a -> m b) instance Contravariant (Thrower m) where contramap :: forall a' a. (a' -> a) -> Thrower m a -> Thrower m a' contramap a' -> a f (Thrower forall b. a -> m b t) = forall (m :: * -> *) a. (forall b. a -> m b) -> Thrower m a Thrower (forall b. a -> m b t forall b c a. (b -> c) -> (a -> b) -> a -> c . a' -> a f) throwWith :: Thrower m a -> a -> m b throwWith :: forall (m :: * -> *) a b. Thrower m a -> a -> m b throwWith (Thrower forall b. a -> m b t) a a = forall b. a -> m b t a a withTracer :: Monad m => Tracer m a -> Thrower m a -> Thrower m a withTracer :: forall (m :: * -> *) a. Monad m => Tracer m a -> Thrower m a -> Thrower m a withTracer (Tracer a -> m () tr) (Thrower forall b. a -> m b th) = forall (m :: * -> *) a. (forall b. a -> m b) -> Thrower m a Thrower forall a b. (a -> b) -> a -> b $ \a m -> a -> m () tr a m forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> forall b. a -> m b th a m