{-# LANGUAGE CPP #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE Rank2Types #-}
module Data.FFunctor where
#ifdef HAVE_TRANSFORMERS
import Control.Monad.Trans.Class (MonadTrans, lift)
#endif
import Control.Monad.IO.Class (MonadIO, liftIO)
class FFunctor (f :: (* -> *) -> *) where
ffmap :: (Functor m, Functor n) => (forall a . (m a -> n a)) -> f m -> f n
luftIO :: FFunctor f => MonadIO m => f IO -> f m
luftIO = ffmap liftIO
#ifdef HAVE_TRANSFORMERS
luft :: FFunctor f => Monad m => MonadTrans t => Functor (t m) => f m -> f (t m)
luft = ffmap lift
#endif