dep-t-0.6.8.0: Dependency injection for records-of-functions.
Safe HaskellSafe-Inferred
LanguageHaskell2010

Dep.Phases

Synopsis

Managing phases

class Phased (env_ :: (Type -> Type) -> (Type -> Type) -> Type) where Source #

Class of 2-parameter environments for which the first parameter h wraps each field and corresponds to phases in the construction of the environment, and the second parameter m is the effect monad used by each component.

h will typically be a composition of applicative functors, each one representing a phase. We advance through the phases by "pulling out" the outermost phase and running it in some way, until we are are left with a Constructor phase, which we can remove using fixEnv.

Phased resembles FunctorT, TraversableT and ApplicativeT from the barbies library, although Phased instances can't be written in terms of them because of the extra Typeable constraints.

Minimal complete definition

Nothing

Methods

traverseH Source #

Arguments

:: forall (h :: Type -> Type) (f :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type). (Applicative f, Typeable f, Typeable g, Typeable h, Typeable m) 
=> (forall x. Typeable x => h x -> f (g x))

Transform to be applied to each field.

-> env_ h m 
-> f (env_ g m) 

Used to implement pullPhase and mapPhase, typically you should use those functions instead.

default traverseH :: forall (h :: Type -> Type) (f :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type). (Applicative f, Typeable f, Typeable g, Typeable h, Typeable m, Generic (env_ h m), Generic (env_ g m), GTraverseH h g (Rep (env_ h m)) (Rep (env_ g m))) => (forall x. Typeable x => h x -> f (g x)) -> env_ h m -> f (env_ g m) Source #

liftA2H Source #

Arguments

:: forall (a :: Type -> Type) (f :: Type -> Type) (f' :: Type -> Type) (m :: Type -> Type). (Typeable a, Typeable f, Typeable f', Typeable m) 
=> (forall x. Typeable x => a x -> f x -> f' x)

Transform to be applied to each field.

-> env_ a m 
-> env_ f m 
-> env_ f' m 

Used to implement liftA2Phase, typically you should use that function instead.

default liftA2H :: forall (a :: Type -> Type) (f :: Type -> Type) (f' :: Type -> Type) m. (Typeable a, Typeable f, Typeable f', Typeable m, Generic (env_ a m), Generic (env_ f m), Generic (env_ f' m), GLiftA2Phase a f f' (Rep (env_ a m)) (Rep (env_ f m)) (Rep (env_ f' m))) => (forall x. Typeable x => a x -> f x -> f' x) -> env_ a m -> env_ f m -> env_ f' m Source #

Instances

Instances details
Phased (InductiveEnv rs) Source # 
Instance details

Defined in Dep.Env

Methods

traverseH :: forall h f g (m :: Type -> Type). (Applicative f, Typeable f, Typeable g, Typeable h, Typeable m) => (forall x. Typeable x => h x -> f (g x)) -> InductiveEnv rs h m -> f (InductiveEnv rs g m) Source #

liftA2H :: forall a f f' (m :: Type -> Type). (Typeable a, Typeable f, Typeable f', Typeable m) => (forall x. Typeable x => a x -> f x -> f' x) -> InductiveEnv rs a m -> InductiveEnv rs f m -> InductiveEnv rs f' m Source #

liftAH Source #

Arguments

:: forall deps_ phases phases' m. (Phased deps_, Typeable phases, Typeable phases', Typeable m) 
=> (forall x. Typeable x => phases x -> phases' x)

Transform to be applied to each field.

-> deps_ phases m 
-> deps_ phases' m 

Slightly less powerful version of traverseH.

pullPhase Source #

Arguments

:: forall (f :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type) env_. (Phased env_, Applicative f, Typeable f, Typeable g, Typeable m) 
=> env_ (Compose f g) m 
-> f (env_ g m)

Environment with the outer Applicative layer pulled outward.

Take the outermost phase wrapping each component and "pull it outwards", aggregating the phase's applicative effects.

>>> :{
 newtype Foo d = Foo {foo :: String -> d ()} deriving Generic
 makeIOFoo :: MonadIO m => Foo m
 makeIOFoo = Foo (liftIO . putStrLn)
 env :: InductiveEnv '[Foo] (IO `Compose` Constructor (InductiveEnv '[Foo] Identity IO)) IO
 env = EmptyEnv
     & AddDep @Foo (putStrLn "io phase" `bindPhase` \() -> constructor (\_ -> makeIOFoo))
 ioOutside :: IO (InductiveEnv '[Foo] (Constructor (InductiveEnv '[Foo] Identity IO)) IO)
 ioOutside = pullPhase env
:}

mapPhase Source #

Arguments

:: forall (f :: Type -> Type) (f' :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type) env_. (Phased env_, Typeable f, Typeable f', Typeable g, Typeable m) 
=> (forall x. Typeable x => f x -> f' x)

Transform to be applied to each field.

-> env_ (Compose f g) m 
-> env_ (Compose f' g) m 

Modify the outermost phase wrapping each component.

>>> :{
 newtype Foo d = Foo {foo :: String -> d ()} deriving Generic
 makeIOFoo :: MonadIO m => Foo m
 makeIOFoo = Foo (liftIO . putStrLn)
 env :: InductiveEnv '[Foo] ((,) Int `Compose` Constructor String) IO
 env = EmptyEnv
     & AddDep @Foo ((2,()) `bindPhase` \() -> constructor (\_ -> makeIOFoo))
 env' :: InductiveEnv '[Foo] ((,) String `Compose` Constructor String) IO
 env' = mapPhase (\(n,x) -> (show n,x)) env
:}

liftA2Phase Source #

Arguments

:: forall (a :: Type -> Type) (f' :: Type -> Type) (f :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type) env_. (Phased env_, Typeable a, Typeable f, Typeable f', Typeable g, Typeable m) 
=> (forall x. Typeable x => a x -> f x -> f' x)

Binary operation to combine corresponding fields.

-> env_ (Compose a g) m 
-> env_ (Compose f g) m 
-> env_ (Compose f' g) m 

Combine two environments with a function that works on their outermost phases.

Qualified do-notation for building phases

Convenient qualified do-notation for defining nested applicative phases wrapped in Composes.

BEWARE! Despite its convenience, this do-notation lacks many of the properties we tend to assume when working with do-notation. In particular, it's NOT associative! This means that if we have

Dep.Phases.do    
   somePhase
   someOtherPhase
   finalPhase

we CAN'T refactor to

Dep.Phases.do    
   Dep.Phases.do 
     somePhase
     someOtherPhase
   finalPhase

It would indeed be useful (it would allow pre-packaging and sharing initial phases as do-blocks) but it isn't supported.

BEWARE#2! Do not use return in this do-notation.

Some valid examples:

>>> :{
type Phases = (IO `Compose` IO `Compose` IO) Int
phases :: Phases
phases = Dep.Phases.do
   r1 <- pure 1
   r2 <- pure 2
   pure $ r1 + r2
:}
>>> :{
type Phases = (IO `Compose` Maybe `Compose` Either Char) Int
phases :: Phases
phases = Dep.Phases.do
   pure ()
   Just 5
   Left 'e'
:}

(>>=) :: Functor f => f x -> (x -> g y) -> Compose f g y Source #

Examples without -XQualifiedDo:

>>> :{
 type Phases = IO `Compose` IO `Compose` Identity
 phased :: Phases Int
 phased =
     pure 1 Dep.Phases.>>= \i1 ->
     pure 2 Dep.Phases.>>= \i2 ->
     pure $ i1 + i2
:}
>>> :{
type Phases = (IO `Compose` Maybe `Compose` Either Char) Int
phases :: Phases
phases = 
   pure () Dep.Phases.>>= \_ ->
   Just 5 Dep.Phases.>>= \_ ->
   Left 'e'
:}

(>>) :: Functor f => f x -> g y -> Compose f g y Source #

Better not use this one without -XQualifiedDo

Re-exports

newtype Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) infixr 9 #

Right-to-left composition of functors. The composition of applicative functors is always applicative, but the composition of monads is not always a monad.

Constructors

Compose infixr 9 

Fields

Instances

Instances details
TestEquality f => TestEquality (Compose f g :: k2 -> Type)

The deduction (via generativity) that if g x :~: g y then x :~: y.

Since: base-4.14.0.0

Instance details

Defined in Data.Functor.Compose

Methods

testEquality :: forall (a :: k) (b :: k). Compose f g a -> Compose f g b -> Maybe (a :~: b) #

Functor f => Generic1 (Compose f g :: k -> Type) 
Instance details

Defined in Data.Functor.Compose

Associated Types

type Rep1 (Compose f g) :: k -> Type #

Methods

from1 :: forall (a :: k0). Compose f g a -> Rep1 (Compose f g) a #

to1 :: forall (a :: k0). Rep1 (Compose f g) a -> Compose f g a #

(Foldable f, Foldable g) => Foldable (Compose f g)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

fold :: Monoid m => Compose f g m -> m #

foldMap :: Monoid m => (a -> m) -> Compose f g a -> m #

foldMap' :: Monoid m => (a -> m) -> Compose f g a -> m #

foldr :: (a -> b -> b) -> b -> Compose f g a -> b #

foldr' :: (a -> b -> b) -> b -> Compose f g a -> b #

foldl :: (b -> a -> b) -> b -> Compose f g a -> b #

foldl' :: (b -> a -> b) -> b -> Compose f g a -> b #

foldr1 :: (a -> a -> a) -> Compose f g a -> a #

foldl1 :: (a -> a -> a) -> Compose f g a -> a #

toList :: Compose f g a -> [a] #

null :: Compose f g a -> Bool #

length :: Compose f g a -> Int #

elem :: Eq a => a -> Compose f g a -> Bool #

maximum :: Ord a => Compose f g a -> a #

minimum :: Ord a => Compose f g a -> a #

sum :: Num a => Compose f g a -> a #

product :: Num a => Compose f g a -> a #

(Eq1 f, Eq1 g) => Eq1 (Compose f g)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

liftEq :: (a -> b -> Bool) -> Compose f g a -> Compose f g b -> Bool #

(Ord1 f, Ord1 g) => Ord1 (Compose f g)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

liftCompare :: (a -> b -> Ordering) -> Compose f g a -> Compose f g b -> Ordering #

(Read1 f, Read1 g) => Read1 (Compose f g)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

liftReadsPrec :: (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (Compose f g a) #

liftReadList :: (Int -> ReadS a) -> ReadS [a] -> ReadS [Compose f g a] #

liftReadPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec (Compose f g a) #

liftReadListPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec [Compose f g a] #

(Show1 f, Show1 g) => Show1 (Compose f g)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> Compose f g a -> ShowS #

liftShowList :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> [Compose f g a] -> ShowS #

(Traversable f, Traversable g) => Traversable (Compose f g)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

traverse :: Applicative f0 => (a -> f0 b) -> Compose f g a -> f0 (Compose f g b) #

sequenceA :: Applicative f0 => Compose f g (f0 a) -> f0 (Compose f g a) #

mapM :: Monad m => (a -> m b) -> Compose f g a -> m (Compose f g b) #

sequence :: Monad m => Compose f g (m a) -> m (Compose f g a) #

(Alternative f, Applicative g) => Alternative (Compose f g)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

empty :: Compose f g a #

(<|>) :: Compose f g a -> Compose f g a -> Compose f g a #

some :: Compose f g a -> Compose f g [a] #

many :: Compose f g a -> Compose f g [a] #

(Applicative f, Applicative g) => Applicative (Compose f g)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

pure :: a -> Compose f g a #

(<*>) :: Compose f g (a -> b) -> Compose f g a -> Compose f g b #

liftA2 :: (a -> b -> c) -> Compose f g a -> Compose f g b -> Compose f g c #

(*>) :: Compose f g a -> Compose f g b -> Compose f g b #

(<*) :: Compose f g a -> Compose f g b -> Compose f g a #

(Functor f, Functor g) => Functor (Compose f g)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

fmap :: (a -> b) -> Compose f g a -> Compose f g b #

(<$) :: a -> Compose f g b -> Compose f g a #

(Typeable a, Typeable f, Typeable g, Typeable k1, Typeable k2, Data (f (g a))) => Data (Compose f g a)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g0. g0 -> c g0) -> Compose f g a -> c (Compose f g a) #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Compose f g a) #

toConstr :: Compose f g a -> Constr #

dataTypeOf :: Compose f g a -> DataType #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Compose f g a)) #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Compose f g a)) #

gmapT :: (forall b. Data b => b -> b) -> Compose f g a -> Compose f g a #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Compose f g a -> r #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Compose f g a -> r #

gmapQ :: (forall d. Data d => d -> u) -> Compose f g a -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Compose f g a -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Compose f g a -> m (Compose f g a) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Compose f g a -> m (Compose f g a) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Compose f g a -> m (Compose f g a) #

Monoid (f (g a)) => Monoid (Compose f g a)

Since: base-4.16.0.0

Instance details

Defined in Data.Functor.Compose

Methods

mempty :: Compose f g a #

mappend :: Compose f g a -> Compose f g a -> Compose f g a #

mconcat :: [Compose f g a] -> Compose f g a #

Semigroup (f (g a)) => Semigroup (Compose f g a)

Since: base-4.16.0.0

Instance details

Defined in Data.Functor.Compose

Methods

(<>) :: Compose f g a -> Compose f g a -> Compose f g a #

sconcat :: NonEmpty (Compose f g a) -> Compose f g a #

stimes :: Integral b => b -> Compose f g a -> Compose f g a #

Generic (Compose f g a) 
Instance details

Defined in Data.Functor.Compose

Associated Types

type Rep (Compose f g a) :: Type -> Type #

Methods

from :: Compose f g a -> Rep (Compose f g a) x #

to :: Rep (Compose f g a) x -> Compose f g a #

(Read1 f, Read1 g, Read a) => Read (Compose f g a)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

readsPrec :: Int -> ReadS (Compose f g a) #

readList :: ReadS [Compose f g a] #

readPrec :: ReadPrec (Compose f g a) #

readListPrec :: ReadPrec [Compose f g a] #

(Show1 f, Show1 g, Show a) => Show (Compose f g a)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

showsPrec :: Int -> Compose f g a -> ShowS #

show :: Compose f g a -> String #

showList :: [Compose f g a] -> ShowS #

(Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

(==) :: Compose f g a -> Compose f g a -> Bool #

(/=) :: Compose f g a -> Compose f g a -> Bool #

(Ord1 f, Ord1 g, Ord a) => Ord (Compose f g a)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

Methods

compare :: Compose f g a -> Compose f g a -> Ordering #

(<) :: Compose f g a -> Compose f g a -> Bool #

(<=) :: Compose f g a -> Compose f g a -> Bool #

(>) :: Compose f g a -> Compose f g a -> Bool #

(>=) :: Compose f g a -> Compose f g a -> Bool #

max :: Compose f g a -> Compose f g a -> Compose f g a #

min :: Compose f g a -> Compose f g a -> Compose f g a #

type Rep1 (Compose f g :: k -> Type)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

type Rep1 (Compose f g :: k -> Type) = D1 ('MetaData "Compose" "Data.Functor.Compose" "base" 'True) (C1 ('MetaCons "Compose" 'PrefixI 'True) (S1 ('MetaSel ('Just "getCompose") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (f :.: Rec1 g)))
type Rep (Compose f g a)

Since: base-4.9.0.0

Instance details

Defined in Data.Functor.Compose

type Rep (Compose f g a) = D1 ('MetaData "Compose" "Data.Functor.Compose" "base" 'True) (C1 ('MetaCons "Compose" 'PrefixI 'True) (S1 ('MetaSel ('Just "getCompose") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f (g a)))))