{-# LANGUAGE FlexibleContexts #-} module Data.Universe.Instances.Trans ( -- | Instances of 'Universe' and 'Finite' for the standard monad and functor transformers. Universe(..), Finite(..) ) where import Control.Monad.Identity import Control.Monad.Reader import Control.Monad.Trans.Identity import Data.Functor.Compose import Data.Functor.Product import Data.Universe.Helpers import Data.Universe.Instances.Base instance Universe a => Universe (Identity a) where universe = map Identity universe instance Universe (f a) => Universe (IdentityT f a) where universe = map IdentityT universe instance (Finite e, Ord e, Universe (m a)) => Universe (ReaderT e m a) where universe = map ReaderT universe instance Universe (f (g a)) => Universe (Compose f g a) where universe = map Compose universe instance (Universe (f a), Universe (g a)) => Universe (Product f g a) where universe = [Pair f g | (f, g) <- universe +*+ universe] instance Finite a => Finite (Identity a) where universeF = map Identity universeF instance Finite (f a) => Finite (IdentityT f a) where universeF = map IdentityT universeF instance (Finite e, Ord e, Finite (m a)) => Finite (ReaderT e m a) where universeF = map ReaderT universeF instance Finite (f (g a)) => Finite (Compose f g a) where universeF = map Compose universeF instance (Finite (f a), Finite (g a)) => Finite (Product f g a) where universeF = liftM2 Pair universeF universeF