{-# LANGUAGE CPP #-}{-# LANGUAGE FlexibleContexts #-} #if __GLASGOW_HASKELL__ >= 707 {-# LANGUAGE StandaloneDeriving, DeriveDataTypeable, Safe #-} #elif __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif #ifndef MIN_VERSION_base #define MIN_VERSION_base(x,y,z) 1 #endif ------------------------------------------------------------------------------- |-- Module : Control.Comonad.Trans.Env-- Copyright : (C) 2008-2013 Edward Kmett-- License : BSD-style (see the file LICENSE)---- Maintainer : Edward Kmett <ekmett@gmail.com>-- Stability : provisional-- Portability : portable---- The environment comonad holds a value along with some retrievable context.---- This module specifies the environment comonad transformer (aka coreader),-- which is left adjoint to the reader comonad.---- The following sets up an experiment that retains its initial value in the-- background:---- >>> let initial = env 0 0---- Extract simply retrieves the value:---- >>> extract initial-- 0---- Play around with the value, in our case producing a negative value:---- >>> let experiment = fmap (+ 10) initial-- >>> extract experiment-- 10---- Oh noes, something went wrong, 10 isn't very negative! Better restore the-- initial value using the default:---- >>> let initialRestored = experiment =>> ask-- >>> extract initialRestored-- 0----------------------------------------------------------------------------moduleControl.Comonad.Trans.Env(-- * The strict environment comonadEnv ,env ,runEnv -- * The strict environment comonad transformer,EnvT (..),runEnvT ,lowerEnvT -- * Combinators,ask ,asks ,local )where #if !(MIN_VERSION_base(4,8,0)) importControl.Applicative #endif importControl.Comonad importControl.Comonad.Hoist.Class importControl.Comonad.Trans.Class #if __GLASGOW_HASKELL__ < 710 importData.FoldableimportData.Traversable #endif importData.Functor.Identity #if !(MIN_VERSION_base(4,11,0)) importData.Semigroup #endif #ifdef __GLASGOW_HASKELL__ #if __GLASGOW_HASKELL__ >= 707 #define Typeable1 Typeable #endif importData.Data-- $setup-- >>> import Control.Comonad #if __GLASGOW_HASKELL__ >= 707 derivinginstanceTypeableEnvT #else instance(Typeables,Typeable1w)=>Typeable1(EnvTsw)wheretypeOf1dswa=mkTyConAppenvTTyCon[typeOf(sdswa),typeOf1(wdswa)]wheres::EnvTswa->ss=undefinedw::EnvTswa->waw=undefinedenvTTyCon::TyCon #if __GLASGOW_HASKELL__ < 704 envTTyCon=mkTyCon"Control.Comonad.Trans.Env.EnvT" #else envTTyCon=mkTyCon3"comonad-transformers""Control.Comonad.Trans.Env""EnvT" #endif {-# NOINLINEenvTTyCon#-} #endif #if __GLASGOW_HASKELL__ < 707 instance(Typeables,Typeable1w,Typeablea)=>Typeable(EnvTswa)wheretypeOf=typeOfDefault #endif instance(Datae ,Typeable1w,Data( wa),Dataa )=>Data(EnvT e w a )wheregfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> EnvT e w a -> c (EnvT e w a) gfoldlforall d b. Data d => c (d -> b) -> d -> c b f forall g. g -> c g z (EnvT e e w a wa )=(e -> w a -> EnvT e w a) -> c (e -> w a -> EnvT e w a) forall g. g -> c g z e -> w a -> EnvT e w a forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT c (e -> w a -> EnvT e w a) -> e -> c (w a -> EnvT e w a) forall d b. Data d => c (d -> b) -> d -> c b `f` e e c (w a -> EnvT e w a) -> w a -> c (EnvT e w a) forall d b. Data d => c (d -> b) -> d -> c b `f` w a wa toConstr :: EnvT e w a -> Constr toConstrEnvT e w a _=Constr envTConstr gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (EnvT e w a) gunfoldforall b r. Data b => c (b -> r) -> c r k forall r. r -> c r z Constr c =caseConstr -> Int constrIndexConstr c ofInt 1->c (w a -> EnvT e w a) -> c (EnvT e w a) forall b r. Data b => c (b -> r) -> c r k (c (e -> w a -> EnvT e w a) -> c (w a -> EnvT e w a) forall b r. Data b => c (b -> r) -> c r k ((e -> w a -> EnvT e w a) -> c (e -> w a -> EnvT e w a) forall r. r -> c r z e -> w a -> EnvT e w a forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT ))Int _->[Char] -> c (EnvT e w a) forall a. HasCallStack => [Char] -> a error[Char] "gunfold"dataTypeOf :: EnvT e w a -> DataType dataTypeOfEnvT e w a _=DataType envTDataType dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (EnvT e w a)) dataCast1forall d. Data d => c (t d) f =c (t a) -> Maybe (c (EnvT e w a)) forall k1 k2 (c :: k1 -> *) (t :: k2 -> k1) (t' :: k2 -> k1) (a :: k2). (Typeable t, Typeable t') => c (t a) -> Maybe (c (t' a)) gcast1c (t a) forall d. Data d => c (t d) f envTConstr ::ConstrenvTConstr :: Constr envTConstr =DataType -> [Char] -> [[Char]] -> Fixity -> Constr mkConstrDataType envTDataType [Char] "EnvT"[]Fixity Prefix{-# NOINLINEenvTConstr #-}envTDataType ::DataTypeenvTDataType :: DataType envTDataType =[Char] -> [Constr] -> DataType mkDataType[Char] "Control.Comonad.Trans.Env.EnvT"[Constr envTConstr ]{-# NOINLINEenvTDataType #-} #endif typeEnv e =EnvT e IdentitydataEnvT e w a =EnvT e (w a )-- | Create an Env using an environment and a valueenv ::e ->a ->Env e a env :: e -> a -> Env e a env e e a a =e -> Identity a -> Env e a forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT e e (a -> Identity a forall a. a -> Identity a Identitya a )runEnv ::Env e a ->(e ,a )runEnv :: Env e a -> (e, a) runEnv (EnvT e e (Identitya a ))=(e e ,a a )runEnvT ::EnvT e w a ->(e ,w a )runEnvT :: EnvT e w a -> (e, w a) runEnvT (EnvT e e w a wa )=(e e ,w a wa )instanceFunctorw =>Functor(EnvT e w )wherefmap :: (a -> b) -> EnvT e w a -> EnvT e w b fmapa -> b g (EnvT e e w a wa )=e -> w b -> EnvT e w b forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT e e ((a -> b) -> w a -> w b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmapa -> b g w a wa )instanceComonad w =>Comonad (EnvT e w )whereduplicate :: EnvT e w a -> EnvT e w (EnvT e w a) duplicate (EnvT e e w a wa )=e -> w (EnvT e w a) -> EnvT e w (EnvT e w a) forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT e e ((w a -> EnvT e w a) -> w a -> w (EnvT e w a) forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b extend (e -> w a -> EnvT e w a forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT e e )w a wa )extract :: EnvT e w a -> a extract (EnvT e _w a wa )=w a -> a forall (w :: * -> *) a. Comonad w => w a -> a extract w a wa instanceComonadTrans (EnvT e )wherelower :: EnvT e w a -> w a lower (EnvT e _w a wa )=w a wa instance(Monoide ,Applicativem )=>Applicative(EnvT e m )wherepure :: a -> EnvT e m a pure=e -> m a -> EnvT e m a forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT e forall a. Monoid a => a mempty(m a -> EnvT e m a) -> (a -> m a) -> a -> EnvT e m a forall b c a. (b -> c) -> (a -> b) -> a -> c .a -> m a forall (f :: * -> *) a. Applicative f => a -> f a pureEnvT e ef m (a -> b) wf <*> :: EnvT e m (a -> b) -> EnvT e m a -> EnvT e m b <*>EnvT e ea m a wa =e -> m b -> EnvT e m b forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT (e ef e -> e -> e forall a. Monoid a => a -> a -> a `mappend`e ea )(m (a -> b) wf m (a -> b) -> m a -> m b forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*>m a wa )-- | Gets rid of the environment. This differs from 'extract' in that it will-- not continue extracting the value from the contained comonad.lowerEnvT ::EnvT e w a ->w a lowerEnvT :: EnvT e w a -> w a lowerEnvT (EnvT e _w a wa )=w a wa instanceComonadHoist (EnvT e )wherecohoist :: (forall x. w x -> v x) -> EnvT e w a -> EnvT e v a cohoist forall x. w x -> v x l (EnvT e e w a wa )=e -> v a -> EnvT e v a forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT e e (w a -> v a forall x. w x -> v x l w a wa )instance(Semigroupe ,ComonadApply w )=>ComonadApply (EnvT e w )whereEnvT e ef w (a -> b) wf <@> :: EnvT e w (a -> b) -> EnvT e w a -> EnvT e w b <@> EnvT e ea w a wa =e -> w b -> EnvT e w b forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT (e ef e -> e -> e forall a. Semigroup a => a -> a -> a <>e ea )(w (a -> b) wf w (a -> b) -> w a -> w b forall (w :: * -> *) a b. ComonadApply w => w (a -> b) -> w a -> w b <@> w a wa )instanceFoldablew =>Foldable(EnvT e w )wherefoldMap :: (a -> m) -> EnvT e w a -> m foldMapa -> m f (EnvT e _w a w )=(a -> m) -> w a -> m forall (t :: * -> *) m a. (Foldable t, Monoid m) => (a -> m) -> t a -> m foldMapa -> m f w a w instanceTraversablew =>Traversable(EnvT e w )wheretraverse :: (a -> f b) -> EnvT e w a -> f (EnvT e w b) traversea -> f b f (EnvT e e w a w )=e -> w b -> EnvT e w b forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT e e (w b -> EnvT e w b) -> f (w b) -> f (EnvT e w b) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$>(a -> f b) -> w a -> f (w b) forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) traversea -> f b f w a w -- | Retrieves the environment.ask ::EnvT e w a ->e ask :: EnvT e w a -> e ask (EnvT e e w a _)=e e -- | Like 'ask', but modifies the resulting value with a function.---- > asks = f . askasks ::(e ->f )->EnvT e w a ->f asks :: (e -> f) -> EnvT e w a -> f asks e -> f f (EnvT e e w a _)=e -> f f e e -- | Modifies the environment using the specified function.local ::(e ->e' )->EnvT e w a ->EnvT e' w a local :: (e -> e') -> EnvT e w a -> EnvT e' w a local e -> e' f (EnvT e e w a wa )=e' -> w a -> EnvT e' w a forall e (w :: * -> *) a. e -> w a -> EnvT e w a EnvT (e -> e' f e e )w a wa