module Control.Monad.Unpack.Class where
import Control.Applicative
import Control.Monad.Trans.Class
class Unpackable arg where
data UnpackedReaderT arg :: (* -> *) -> * -> *
runUnpackedReaderT :: UnpackedReaderT arg m a -> arg -> m a
unpackedReaderT :: (arg -> m a) -> UnpackedReaderT arg m a
ask :: (Monad m, Unpackable arg) => UnpackedReaderT arg m arg
ask = unpackedReaderT return
local :: (Monad m, Unpackable arg) => (arg -> arg) -> UnpackedReaderT arg m a -> UnpackedReaderT arg m a
local f m = unpackedReaderT $ runUnpackedReaderT m . f
instance Unpackable arg => MonadTrans (UnpackedReaderT arg) where
lift m = unpackedReaderT $ \ _ -> m
instance (Unpackable arg, Monad m) => Monad (UnpackedReaderT arg m) where
return x = lift $ return x
m >>= k = unpackedReaderT $ \ arg ->
do a <- runUnpackedReaderT m arg
runUnpackedReaderT (k a) arg
instance (Unpackable arg, Functor f) => Functor (UnpackedReaderT arg f) where
fmap f m = unpackedReaderT $ \ arg -> fmap f (runUnpackedReaderT m arg)
instance (Unpackable arg, Applicative f) => Applicative (UnpackedReaderT arg f) where
pure f = unpackedReaderT $ \ _ -> pure f
f <*> x = unpackedReaderT $ \ arg -> runUnpackedReaderT f arg <*> runUnpackedReaderT x arg