Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This module provides helpers for building dependency injection environments composed of records.
It's not necessary when defining the record components themselves, in that case Dep.Has should suffice.
>>>
:{
type Logger :: (Type -> Type) -> Type newtype Logger d = Logger { info :: String -> d () } -- data Repository d = Repository { findById :: Int -> d (Maybe String) , putById :: Int -> String -> d () , insert :: String -> d Int } -- data Controller d = Controller { create :: d Int , append :: Int -> String -> d Bool , inspect :: Int -> d (Maybe String) } -- type EnvHKD :: (Type -> Type) -> (Type -> Type) -> Type data EnvHKD h m = EnvHKD { logger :: h (Logger m), repository :: h (Repository m), controller :: h (Controller m) } deriving stock Generic deriving anyclass (FieldsFindableByType, DemotableFieldNames, Phased) deriving via Autowired (EnvHKD Identity m) instance Autowireable r_ m (EnvHKD Identity m) => Has r_ m (EnvHKD Identity m) :}
The module also provides a monad transformer-less way of performing dependency
injection, by means of fixEnv
.
Synopsis
- class Has (r_ :: (Type -> Type) -> Type) (m :: Type -> Type) (deps :: Type) | deps -> m
- newtype TheDefaultFieldName (env :: Type) = TheDefaultFieldName env
- newtype TheFieldName (name :: Symbol) (env :: Type) = TheFieldName env
- class FieldsFindableByType (env :: Type) where
- type FindFieldByType env (r :: Type) :: Symbol
- newtype Autowired (env :: Type) = Autowired env
- type Autowireable r_ (m :: Type -> Type) (env :: Type) = HasField (FindFieldByType env (r_ m)) env (Identity (r_ m))
- data InductiveEnv (rs :: [(Type -> Type) -> Type]) (h :: Type -> Type) (m :: Type -> Type) where
- AddDep :: forall r_ m rs h. Typeable r_ => h (r_ m) -> InductiveEnv rs h m -> InductiveEnv (r_ ': rs) h m
- EmptyEnv :: forall m h. InductiveEnv '[] h m
- addDep :: forall r_ m rs. Typeable r_ => r_ m -> InductiveEnv rs Identity m -> InductiveEnv (r_ ': rs) Identity m
- emptyEnv :: forall m. InductiveEnv '[] Identity m
- class Phased (env_ :: (Type -> Type) -> (Type -> Type) -> Type) where
- traverseH :: 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)) -> env_ h m -> f (env_ g m)
- liftA2H :: 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) -> env_ a m -> env_ f m -> env_ f' m
- liftAH :: forall deps_ phases phases' m. (Phased deps_, Typeable phases, Typeable phases', Typeable m) => (forall x. Typeable x => phases x -> phases' x) -> deps_ phases m -> deps_ phases' m
- pullPhase :: 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)
- mapPhase :: 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) -> env_ (Compose f g) m -> env_ (Compose f' g) m
- liftA2Phase :: 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) -> env_ (Compose a g) m -> env_ (Compose f g) m -> env_ (Compose f' g) m
- class DemotableFieldNames env_ where
- demoteFieldNamesH :: (forall x. String -> h String x) -> env_ (h String) m
- demoteFieldNames :: forall env_ m. DemotableFieldNames env_ => env_ (Constant String) m
- mapPhaseWithFieldNames :: forall (f :: Type -> Type) (f' :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type) env_. (Phased env_, DemotableFieldNames env_, Typeable f, Typeable f', Typeable g, Typeable m) => (forall x. Typeable x => String -> f x -> f' x) -> env_ (Compose f g) m -> env_ (Compose f' g) m
- bindPhase :: forall f g a b. Functor f => f a -> (a -> g b) -> Compose f g b
- skipPhase :: forall f g a. Applicative f => g a -> Compose f g a
- type family Bare x where ...
- fromBare :: Coercible phases (Bare phases) => Bare phases -> phases
- toBare :: Coercible phases (Bare phases) => phases -> Bare phases
- fixEnv :: (Phased env_, Typeable env_, Typeable m) => env_ (Constructor (env_ Identity m)) m -> env_ Identity m
- type Constructor (env :: Type) = (->) env `Compose` Identity
- constructor :: forall r_ m env. (env -> r_ m) -> Constructor env (r_ m)
- fixEnvAccum :: (Phased env_, Typeable env_, Typeable m, Monoid w, Typeable w) => env_ (AccumConstructor w (env_ Identity m)) m -> (w, env_ Identity m)
- type AccumConstructor (w :: Type) (env :: Type) = (->) (w, env) `Compose` ((,) w `Compose` Identity)
- newtype Identity a = Identity {
- runIdentity :: a
- newtype Constant a (b :: k) = Constant {
- getConstant :: a
- newtype Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) = Compose {
- getCompose :: f (g a)
A general-purpose Has
class Has (r_ :: (Type -> Type) -> Type) (m :: Type -> Type) (deps :: Type) | deps -> m Source #
A generic "Has" class. When partially applied to a parametrizable
record-of-functions r_
, produces a 2-place constraint
saying that the environment deps
has the record r_
with effect monad m
.
The constraint can be used on its own, or with Control.Monad.Dep.Class.
Instances
(FieldsFindableByType (env_ m), HasField (FindFieldByType (env_ m) (r_ m)) (env_ m) u, Coercible u (r_ m)) => Has r_ m (Autowired (env_ m)) Source # | |
(Dep r_, HasField (DefaultFieldName r_) (env_ m) u, Coercible u (r_ m)) => Has r_ m (TheDefaultFieldName (env_ m)) Source # | |
Defined in Dep.Env dep :: TheDefaultFieldName (env_ m) -> r_ m Source # | |
(HasField name (env_ m) u, Coercible u (r_ m)) => Has r_ m (TheFieldName name (env_ m)) Source # | |
Defined in Dep.Env dep :: TheFieldName name (env_ m) -> r_ m Source # | |
Has r_ m (a, r_ m) Source # | |
Has r_ m (r_ m, b) Source # | |
InductiveEnvFind r_ m rs => Has r_ m (InductiveEnv rs Identity m) Source # | Works by searching on the list of types. |
Has r_ m (a, b, r_ m) Source # | |
Has r_ m (a, r_ m, c) Source # | |
Has r_ m (r_ m, b, c) Source # | |
Has r_ m (a, b, c, r_ m) Source # | |
Has r_ m (a, b, r_ m, d) Source # | |
Has r_ m (a, r_ m, c, d) Source # | |
Has r_ m (r_ m, b, c, d) Source # | |
Helpers for deriving Has
via the default field name
newtype TheDefaultFieldName (env :: Type) Source #
Deprecated: more intrusive than useful
Helper for DerivingVia
HasField
instances.
It expects the component to have as field name the default fieldname
specified by Dep
.
This is the same behavior as the DefaultSignatures
implementation for
Has
, so maybe it doesn't make much sense to use it, except for
explicitness.
TheDefaultFieldName env | Deprecated: more intrusive than useful |
Instances
(Dep r_, HasField (DefaultFieldName r_) (env_ m) u, Coercible u (r_ m)) => Has r_ m (TheDefaultFieldName (env_ m)) Source # | |
Defined in Dep.Env dep :: TheDefaultFieldName (env_ m) -> r_ m Source # |
via arbitrary field name
newtype TheFieldName (name :: Symbol) (env :: Type) Source #
TheFieldName env |
via autowiring
class FieldsFindableByType (env :: Type) Source #
Class for getting the field name from the field's type.
The default implementation of FindFieldByType
requires a Generic
instance, but users can write their own implementations.
type FindFieldByType env (r :: Type) :: Symbol Source #
type FindFieldByType env r = FindFieldByType_ env r
newtype Autowired (env :: Type) Source #
Helper for DerivingVia
HasField
instances.
The fields are identified by their types.
It uses FindFieldByType
under the hood.
BEWARE: for large records with many components, this technique might incur in long compilation times.
Autowired env |
type Autowireable r_ (m :: Type -> Type) (env :: Type) = HasField (FindFieldByType env (r_ m)) env (Identity (r_ m)) Source #
Constraints required when DerivingVia
all possible instances of Has
in
a single definition.
This only works for environments where all the fields come wrapped in Data.Functor.Identity.
Inductive environment with anonymous fields
data InductiveEnv (rs :: [(Type -> Type) -> Type]) (h :: Type -> Type) (m :: Type -> Type) where Source #
An inductively constructed environment with anonymous fields.
Can be useful for simple tests. Also for converting Has
-based
components into functions that take their dependencies as separate
positional parameters.
>>>
:{
data Logger d = Logger { } data Repository d = Repository { } data Controller d = Controller { } makeController :: (Monad m, Has Logger m deps, Has Repository m deps) => deps -> Controller m makeController = undefined makeControllerPositional :: Monad m => Logger m -> Repository m -> Controller m makeControllerPositional a b = makeController $ addDep @Logger a $ addDep @Repository b $ emptyEnv makeController' :: (Monad m, Has Logger m deps, Has Repository m deps) => deps -> Controller m makeController' deps = makeControllerPositional (dep deps) (dep deps) :}
Although, for small numbers of components, we can simply use a tuple as the environment:
>>>
:{
makeControllerPositional' :: Monad m => Logger m -> Repository m -> Controller m makeControllerPositional' a b = makeController (a,b) :}
AddDep :: forall r_ m rs h. Typeable r_ => h (r_ m) -> InductiveEnv rs h m -> InductiveEnv (r_ ': rs) h m | |
EmptyEnv :: forall m h. InductiveEnv '[] h m |
Instances
InductiveEnvFind r_ m rs => Has r_ m (InductiveEnv rs Identity m) Source # | Works by searching on the list of types. |
Phased (InductiveEnv rs) Source # | |
Defined in Dep.Env 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 # |
addDep :: forall r_ m rs. Typeable r_ => r_ m -> InductiveEnv rs Identity m -> InductiveEnv (r_ ': rs) Identity m Source #
emptyEnv :: forall m. InductiveEnv '[] Identity m Source #
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.
Nothing
:: 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) |
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 #
:: 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
Phased (InductiveEnv rs) Source # | |
Defined in Dep.Env 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 # |
:: 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
.
:: 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 |
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 :}
:: 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 :}
:: 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.
Working with field names
class DemotableFieldNames env_ where Source #
Deprecated: using the field names directly is usually a bad idea
Class of 2-parameter environments for which it's possible to obtain the names of each field as values.
Nothing
demoteFieldNames :: forall env_ m. DemotableFieldNames env_ => env_ (Constant String) m Source #
Deprecated: using the field names directly is usually a bad idea
Bring down the field names of the environment to the term level and store them in the accumulator of Data.Functor.Constant.
mapPhaseWithFieldNames Source #
:: forall (f :: Type -> Type) (f' :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type) env_. (Phased env_, DemotableFieldNames env_, Typeable f, Typeable f', Typeable g, Typeable m) | |
=> (forall x. Typeable x => String -> f x -> f' x) | Transform to be applied to each field. Has access to the field name. |
-> env_ (Compose f g) m | |
-> env_ (Compose f' g) m |
Deprecated: using the field names directly is usually a bad idea
Modify the outermost phase wrapping each component, while having access to the field name of the component.
A typical usage is modifying a "parsing the configuration" phase so that each component looks into a different section of the global configuration field.
Constructing phases
bindPhase
and skipPhase
are small convenience functions to help build nested compositions of functors.
bindPhase :: forall f g a b. Functor f => f a -> (a -> g b) -> Compose f g b Source #
Use the result of the previous phase to build the next one.
Can be useful infix.
>>>
:{
type Phases = IO `Compose` IO `Compose` Identity phased :: Phases Int phased = pure 1 `bindPhase` \i1 -> pure 2 `bindPhase` \i2 -> Identity (i1 + i2) :}
A possible alternative is >>=
from Dep.Phases used in
combination with -XQualifiedDo
.
skipPhase :: forall f g a. Applicative f => g a -> Compose f g a Source #
Deprecated: use pure () in combination with bindPhase
Don't do anything for the current phase, just wrap the next one.
>>>
:{
type Phases = IO `Compose` IO `Compose` Identity phased :: Phases Int phased = skipPhase $ skipPhase $ Identity 1 :}
fromBare
and toBare
are an alternative method to build nested compositions of functors, which relies on "coerce".
type family Bare x where ... Source #
This type family clears newtypes like Compose
, Identity
and Constant
from a composite type,
leaving you with a newtypeless nested type as result.
The idea is that it might be easier to construct values of the "bare" version of a composite type,
and later coerce them to the newtyped version using fromBare
.
This is mainly intended for defining the nested Applicative
"phases" of components that live in a Phased
environment. It's an alternative to functions like bindPhase
and skipPhase
.
fromBare :: Coercible phases (Bare phases) => Bare phases -> phases Source #
Convert a value from its bare version to the newtyped one, usually as a step
towards inserting it into a Phased
environment.
>>>
:{
type Phases = IO `Compose` IO `Compose` IO wrapped :: Phases Int = fromBare $ pure $ pure $ pure 3 :}
>>>
:{
type Phases = Constructor Int wrapped :: Phases Int wrapped = fromBare $ succ :}
>>>
:{
type Phases = IO `Compose` Constructor Int wrapped :: Phases Int wrapped = fromBare $ pure $ succ :}
toBare :: Coercible phases (Bare phases) => phases -> Bare phases Source #
Convert from the newtyped value to the bare one. fromBare
tends to be more useful.
Injecting dependencies by tying the knot
:: (Phased env_, Typeable env_, Typeable m) | |
=> env_ (Constructor (env_ Identity m)) m | Environment where each field is wrapped in a |
-> env_ Identity m | Fully constructed environment, ready for use. |
Deprecated: use the one in Dep.Constructor
This is a method of performing dependency injection that doesn't require Control.Monad.Dep.DepT at all. In fact, it doesn't require the use of any monad transformer!
If we have a environment whose fields are functions that construct each component by searching for its dependencies in a "fully built" version of the environment, we can "tie the knot" to obtain the "fully built" environment. This works as long as there aren't any circular dependencies between components.
Think of it as a version of fix
that, instead of "tying" a single
function, ties a whole record of them.
The env_ (Constructor (env_ Identity m)) m
parameter might be the result of peeling
away successive layers of applicative functor composition using pullPhase
,
until only the wiring phase remains.
>>>
:{
newtype Foo d = Foo {foo :: String -> d ()} deriving Generic newtype Bar d = Bar {bar :: String -> d ()} deriving Generic makeIOFoo :: MonadIO m => Foo m makeIOFoo = Foo (liftIO . putStrLn) makeBar :: Has Foo m env => env -> Bar m makeBar (asCall -> call) = Bar (call foo) env :: InductiveEnv [Bar,Foo] (Constructor (InductiveEnv [Bar,Foo] Identity IO)) IO env = EmptyEnv & AddDep @Foo (constructor (\_ -> makeIOFoo)) & AddDep @Bar (constructor makeBar) envReady :: InductiveEnv [Bar,Foo] Identity IO envReady = fixEnv env :}
>>>
:{
bar (dep envReady) "this is bar" :} this is bar
type Constructor (env :: Type) = (->) env `Compose` Identity Source #
Deprecated: use the one in Dep.Constructor
A phase with the effect of "constructing each component by reading its dependencies from a completed environment". It should be the final phase.
The Constructor
phase for an environment will typically be parameterized
with the environment itself.
constructor :: forall r_ m env. (env -> r_ m) -> Constructor env (r_ m) Source #
Deprecated: use the one in Dep.Constructor
Turn an environment-consuming function into a Constructor
that can be slotted
into some field of a Phased
environment.
:: (Phased env_, Typeable env_, Typeable m, Monoid w, Typeable w) | |
=> env_ (AccumConstructor w (env_ Identity m)) m | Environment where each field is wrapped in an |
-> (w, env_ Identity m) | Fully constructed accumulator and environment, ready for use. |
Deprecated: use the one in Dep.Constructor
A generalized version of fixEnv
which threads a monoidal accumulator
along with the environment.
Sometimes, we need constructors to produce a monoidal value along with the component. Think for example about some kind of composable startup action for the component.
And on the input side, some constructors need access to the monoidal value accumulated across all components. Think for example about a component which publishes accumulated diagnostics coming from all other components.
LAZY PATTERN MATCH REQUIRED! Any constructor that matches on the
(accumulator, environment) tuple needs to use a lazy pattern match like
~(w,env)
. Otherwise fixEnvAccum
enters an infinite loop! Such are the
dangers of knot-tying.
type AccumConstructor (w :: Type) (env :: Type) = (->) (w, env) `Compose` ((,) w `Compose` Identity) Source #
Deprecated: use the one in Dep.Constructor
A generalization of Constructor
which produces, in addition to the result
value, a value w
which is then aggregated across all components and fed
back along with the completed environment.
Like Constructor
, AccumConstructor
should be the final phase.
Re-exports
Identity functor and monad. (a non-strict monad)
Since: base-4.8.0.0
Identity | |
|
Instances
Constant functor.
Constant | |
|
Instances
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.
Compose infixr 9 | |
|
Instances
TestEquality f => TestEquality (Compose f g :: k2 -> Type) | The deduction (via generativity) that if Since: base-4.14.0.0 |
Defined in Data.Functor.Compose | |
Functor f => Generic1 (Compose f g :: k -> Type) | |
(Foldable f, Foldable g) => Foldable (Compose f g) | Since: base-4.9.0.0 |
Defined in Data.Functor.Compose 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 # | |
(Eq1 f, Eq1 g) => Eq1 (Compose f g) | Since: base-4.9.0.0 |
(Ord1 f, Ord1 g) => Ord1 (Compose f g) | Since: base-4.9.0.0 |
Defined in Data.Functor.Compose | |
(Read1 f, Read1 g) => Read1 (Compose f g) | Since: base-4.9.0.0 |
Defined in Data.Functor.Compose 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 |
(Traversable f, Traversable g) => Traversable (Compose f g) | Since: base-4.9.0.0 |
Defined in Data.Functor.Compose | |
(Alternative f, Applicative g) => Alternative (Compose f g) | Since: base-4.9.0.0 |
(Applicative f, Applicative g) => Applicative (Compose f g) | Since: base-4.9.0.0 |
Defined in Data.Functor.Compose | |
(Functor f, Functor g) => Functor (Compose f g) | Since: base-4.9.0.0 |
(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 |
Defined in Data.Functor.Compose 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 |
Semigroup (f (g a)) => Semigroup (Compose f g a) | Since: base-4.16.0.0 |
Generic (Compose f g a) | |
(Read1 f, Read1 g, Read a) => Read (Compose f g a) | Since: base-4.9.0.0 |
(Show1 f, Show1 g, Show a) => Show (Compose f g a) | Since: base-4.9.0.0 |
(Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) | Since: base-4.9.0.0 |
(Ord1 f, Ord1 g, Ord a) => Ord (Compose f g a) | Since: base-4.9.0.0 |
Defined in Data.Functor.Compose 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 # | |
type Rep1 (Compose f g :: k -> Type) | Since: base-4.9.0.0 |
Defined in Data.Functor.Compose | |
type Rep (Compose f g a) | Since: base-4.9.0.0 |
Defined in Data.Functor.Compose |