{-# LANGUAGE CPP #-}
module Control.Monad.Trans.Edit where
import Control.Applicative (liftA2)
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Control.Monad.Zip
import Data.Edit
import Data.Functor.Classes
#if defined(WITH_COMONAD_INSTANCE)
import Control.Comonad
import Control.Comonad.Trans.Class
#endif
newtype EditT m a = EditT { runEditT :: m (Edit a) }
instance Eq1 m => Eq1 (EditT m) where
liftEq eq (EditT x) (EditT y) = liftEq (liftEq eq) x y
instance Show1 m => Show1 (EditT m) where
liftShowsPrec sp sl d (EditT m) =
showsUnaryWith (liftShowsPrec sp' sl') "EditT" d m
where
sp' = liftShowsPrec sp sl
sl' = liftShowList sp sl
instance Read1 m => Read1 (EditT m) where
liftReadsPrec rp rl = readsData $
readsUnaryWith (liftReadsPrec rp' rl') "EditT" EditT
where
rp' = liftReadsPrec rp rl
rl' = liftReadList rp rl
instance (Eq1 m, Eq a) => Eq (EditT m a) where (==) = eq1
instance (Read1 m, Read a) => Read (EditT m a) where readsPrec = readsPrec1
instance (Show1 m, Show a) => Show (EditT m a) where showsPrec = showsPrec1
mapEditT :: (m (Edit a) -> n (Edit b)) -> EditT m a -> EditT n b
mapEditT f = EditT . f . runEditT
instance Functor m => Functor (EditT m) where
fmap f = mapEditT (fmap (fmap f))
instance Applicative m => Applicative (EditT m) where
pure = EditT . pure . Clean
EditT mf <*> EditT mx = EditT $ liftA2 (<*>) mf mx
instance Monad m => Monad (EditT m) where
return = pure
EditT x >>= f = EditT $ do
v <- x
case v of
Dirty y -> dirty <$> runEditT (f y)
Clean y -> runEditT (f y)
instance MonadTrans EditT where
lift = EditT . fmap Clean
instance MonadIO m => MonadIO (EditT m) where
liftIO = lift . liftIO
instance MonadZip m => MonadZip (EditT m) where
mzip (EditT x) (EditT y) = EditT (liftA2 mzip x y)
instance Foldable f => Foldable (EditT f) where
foldMap f (EditT a) = foldMap (foldMap f) a
instance Traversable f => Traversable (EditT f) where
traverse f (EditT a) = EditT <$> traverse (traverse f) a
#if defined(WITH_COMONAD_INSTANCE)
instance Comonad c => Comonad (EditT c) where
extract = extract . extract . runEditT
duplicate (EditT cex) = EditT ceEcex
where
ef = case extract cex of
Dirty _ -> Dirty
Clean _ -> Clean
ceEcex = fmap (ef . EditT) (duplicate cex)
instance ComonadTrans EditT where
lower = fmap extract . runEditT
#endif