atl-15322.1: Control/Arrow/Reader.hs
module Control.Arrow.Reader (module Control.Arrow.Reader.Class, ReaderT (..), withReaderT) where
import Prelude hiding ((.), id);
import Control.Monad;
import Control.Category;
import Control.Arrow;
import Control.Arrow.Transformer;
import Control.Arrow.Reader.Class;
import Util;
newtype ReaderT r s a b = ReaderT { runReaderT :: s (a, r) b };
instance ArrowTransformer (ReaderT r) where {
lift = ReaderT . (<<< arr fst);
tmap f = ReaderT . f . runReaderT;
};
instance (Arrow s) => Category (ReaderT r s) where {
id = ReaderT (arr fst);
ReaderT f . ReaderT g = ReaderT (f <<< g *** id <<< id &&& arr snd);
};
instance (Arrow s) => Arrow (ReaderT r s) where {
arr = lift . arr;
first = ReaderT . (<<< swap_snds_A) . (*** id) . runReaderT;
};
instance (ArrowApply s) => ArrowApply (ReaderT r s) where {
app = ReaderT (arr (\ ((ReaderT f, x), r) -> (f, (x, r))) >>> app);
};
instance (Arrow s) => ArrowReader r (ReaderT r s) where {
ask = ReaderT (arr snd);
local = withReaderT . arr;
};
instance (Arrow s, ArrowTransformer xT, Arrow (xT (ReaderT r s))) => ArrowReader r (xT (ReaderT r s)) where {
ask = lift ask;
local (f :: r -> r) =
let local' (a :: s r r) = tmap (withReaderT a :: ∀ a b. ReaderT r s a b → ReaderT r s a b);
in local' (arr f);
};
withReaderT :: Arrow s => s q r -> ReaderT r s a b -> ReaderT q s a b;
withReaderT a = ReaderT . (<<< id *** a) . runReaderT;