Copyright  (c) Justin Le 2019 

License  BSD3 
Maintainer  justin@jle.im 
Stability  experimental 
Portability  nonportable 
Safe Haskell  None 
Language  Haskell2010 
Functor combinators and tools (typeclasses and utiility functions) to manipulate them. This is the main "entrypoint" of the library.
Classes include:
HFunctor
andHBifunctor
, used to swap out the functors that the combinators modifyInterpret
,Associative
,Tensor
, used to inject and interpret functor values with respect to their combinators.
We have some helpful utility functions, as well, built on top of these typeclasses.
The second half of this module exports the various useful functor combinators that can modify functors to add extra functionality, or join two functors together and mix them in different ways. Use them to build your final structure by combining simpler ones in composable ways!
See https://blog.jle.im/entry/functorcombinatorpedia.html and the README for a tutorial and a rundown on each different functor combinator.
Synopsis
 type (~>) (f :: k > Type) (g :: k > Type) = forall (x :: k). f x > g x
 type (<~>) f g = forall p a. Profunctor p => p (g a) (g a) > p (f a) (f a)
 class HFunctor t where
 class HFunctor t => Inject t where
 class Inject t => Interpret t f where
 forI :: Interpret t f => t g a > (g ~> f) > f a
 iget :: Interpret t (AltConst b) => (forall x. f x > b) > t f a > b
 icollect :: (forall m. Monoid m => Interpret t (AltConst m)) => (forall x. f x > b) > t f a > [b]
 icollect1 :: (forall m. Semigroup m => Interpret t (AltConst m)) => (forall x. f x > b) > t f a > NonEmpty b
 iapply :: Interpret t (Op b) => (forall x. f x > x > b) > t f a > a > b
 ifanout :: (forall m. Monoid m => Interpret t (Op m)) => (forall x. f x > x > b) > t f a > a > [b]
 ifanout1 :: (forall m. Semigroup m => Interpret t (Op m)) => (forall x. f x > x > b) > t f a > a > NonEmpty b
 getI :: Interpret t (AltConst b) => (forall x. f x > b) > t f a > b
 collectI :: (forall m. Monoid m => Interpret t (AltConst m)) => (forall x. f x > b) > t f a > [b]
 injectMap :: (Inject t, Functor f) => (a > b) > f a > t f b
 injectContramap :: (Inject t, Contravariant f) => (a > b) > f b > t f a
 newtype AltConst w a = AltConst {
 getAltConst :: w
 class HBifunctor (t :: (k > Type) > (k > Type) > k > Type) where
 class (HBifunctor t, Inject (NonEmptyBy t)) => Associative t where
 type NonEmptyBy t :: (Type > Type) > Type > Type
 type FunctorBy t :: (Type > Type) > Constraint
 associating :: (FunctorBy t f, FunctorBy t g, FunctorBy t h) => t f (t g h) <~> t (t f g) h
 appendNE :: t (NonEmptyBy t f) (NonEmptyBy t f) ~> NonEmptyBy t f
 matchNE :: FunctorBy t f => NonEmptyBy t f ~> (f :+: t f (NonEmptyBy t f))
 consNE :: t f (NonEmptyBy t f) ~> NonEmptyBy t f
 toNonEmptyBy :: t f f ~> NonEmptyBy t f
 class (Associative t, FunctorBy t f) => SemigroupIn t f where
 biget :: SemigroupIn t (AltConst b) => (forall x. f x > b) > (forall x. g x > b) > t f g a > b
 biapply :: SemigroupIn t (Op b) => (forall x. f x > x > b) > (forall x. g x > x > b) > t f g a > a > b
 (!*!) :: SemigroupIn t h => (f ~> h) > (g ~> h) > t f g ~> h
 (!+!) :: (f ~> h) > (g ~> h) > (f :+: g) ~> h
 (!$!) :: SemigroupIn t (AltConst b) => (forall x. f x > b) > (forall x. g x > b) > t f g a > b
 class (Associative t, Inject (ListBy t)) => Tensor t i  t > i where
 type ListBy t :: (Type > Type) > Type > Type
 intro1 :: f ~> t f i
 intro2 :: g ~> t i g
 elim1 :: FunctorBy t f => t f i ~> f
 elim2 :: FunctorBy t g => t i g ~> g
 appendLB :: t (ListBy t f) (ListBy t f) ~> ListBy t f
 splitNE :: NonEmptyBy t f ~> t f (ListBy t f)
 splittingLB :: ListBy t f <~> (i :+: t f (ListBy t f))
 toListBy :: t f f ~> ListBy t f
 fromNE :: NonEmptyBy t f ~> ListBy t f
 class (Tensor t i, SemigroupIn t f) => MonoidIn t i f where
 nilLB :: forall t i f. Tensor t i => i ~> ListBy t f
 consLB :: Tensor t i => t f (ListBy t f) ~> ListBy t f
 inL :: forall t i f g. MonoidIn t i g => f ~> t f g
 inR :: forall t i f g. MonoidIn t i f => g ~> t f g
 outL :: (Tensor t Proxy, FunctorBy t f) => t f g ~> f
 outR :: (Tensor t Proxy, FunctorBy t g) => t f g ~> g
 data Coyoneda (f :: Type > Type) a where
 newtype ListF f a = ListF {
 runListF :: [f a]
 newtype NonEmptyF f a where
 NonEmptyF {
 runNonEmptyF :: NonEmpty (f a)
 pattern ProdNonEmpty :: (f :*: ListF f) a > NonEmptyF f a
 NonEmptyF {
 newtype MaybeF f a = MaybeF {}
 newtype MapF k f a = MapF {}
 newtype NEMapF k f a = NEMapF {}
 data Ap (f :: Type > Type) a
 data Ap1 :: (Type > Type) > Type > Type where
 data Alt (f :: Type > Type) a
 data Free f a
 data Free1 f a
 data Lift (f :: Type > Type) a
 data Step f a = Step {}
 newtype Steps f a = Steps {}
 data ProxyF f a = ProxyF
 data ConstF e f a = ConstF {
 getConstF :: e
 data EnvT e (w :: Type > Type) a = EnvT e (w a)
 newtype ReaderT r (m :: Type > Type) a = ReaderT {
 runReaderT :: r > m a
 data Flagged f a = Flagged {
 flaggedFlag :: Bool
 flaggedVal :: f a
 newtype IdentityT (f :: k > Type) (a :: k) = IdentityT {
 runIdentityT :: f a
 data Void2 a b
 newtype Final c f a = Final {
 runFinal :: forall g. c g => (forall x. f x > g x) > g a
 class FreeOf c t  t > c where
 type FreeFunctorBy t :: (Type > Type) > Constraint
 fromFree :: t f ~> Final c f
 toFree :: FreeFunctorBy t f => Final c f ~> t f
 newtype ComposeT (f :: (Type > Type) > Type > Type) (g :: (Type > Type) > Type > Type) (m :: Type > Type) a = ComposeT {
 getComposeT :: f (g m) a
 data Day (f :: Type > Type) (g :: Type > Type) a = Day (f b) (g c) (b > c > a)
 data ((f :: k > Type) :*: (g :: k > Type)) (p :: k) = (f p) :*: (g p)
 prodOutL :: (f :*: g) ~> f
 prodOutR :: (f :*: g) ~> g
 data ((f :: k > Type) :+: (g :: k > Type)) (p :: k)
 data V1 (p :: k)
 data These1 (f :: Type > Type) (g :: Type > Type) a
 data Night :: (Type > Type) > (Type > Type) > Type > Type where
 newtype Not a = Not {}
 refuted :: Not Void
 data Comp f g a where
 newtype LeftF f g a = LeftF {
 runLeftF :: f a
 newtype RightF f g a = RightF {
 runRightF :: g a
 data HLift t f a
 data HFree t f a
 generalize :: Applicative f => Identity ~> f
 absorb :: f ~> Proxy
 dsum :: (Foldable t, Divisible f) => t (f a) > f a
 dsum1 :: (Foldable1 t, Divise f) => t (f a) > f a
 concludeN :: Conclude f => NP f as > f (NS I as)
 decideN :: Decide f => NP f (a ': as) > f (NS I (a ': as))
Classes
A lot of type signatures are stated in terms of ~>
. ~>
represents a "natural transformation" between two functors: a value of
type f
is a value of type 'f a > g a~>
g that works for any
a@.
type (~>) (f :: k > Type) (g :: k > Type) = forall (x :: k). f x > g x infixr 0 #
A natural transformation from f
to g
.
type (<~>) f g = forall p a. Profunctor p => p (g a) (g a) > p (f a) (f a) infixr 0 Source #
The type of an isomorphism between two functors. f
means that
<~>
gf
and g
are isomorphic to each other.
We can effectively use an f <~> g
with:
viewF
:: (f <~> g) > f a > g areviewF
:: (f <~> g) > g a > a a
Use viewF
to extract the "f
to g
" function, and reviewF
to
extract the "g
to f
" function. Reviewing and viewing the same value
(or vice versa) leaves the value unchanged.
One nice thing is that we can compose isomorphisms using .
from
Prelude:
(.
) :: f <~> g
> g <~> h
> f <~> h
Another nice thing about this representation is that we have the
"identity" isomorphism by using id
from Prelude.
id
:: f<~>
g
As a convention, most isomorphisms have form "Xing", where the forwards function is "ing". For example, we have:
splittingSF
::Monoidal
t =>SF
t a<~>
t f (MF
t f)splitSF
:: Monoidal t => SF t a~>
t f (MF t f)
Single Functors
Classes that deal with singlefunctor combinators, that enhance a single functor.
class HFunctor t where Source #
An HFunctor
can be thought of a unary "functor transformer" 
a basic functor combinator. It takes a functor as input and returns
a functor as output.
It "enhances" a functor with extra structure (sort of like how a monad
transformer enhances a Monad
with extra structure).
As a uniform inteface, we can "swap the underlying functor" (also
sometimes called "hoisting"). This is what hmap
does: it lets us swap
out the f
in a t f
for a t g
.
For example, the free monad Free
takes a Functor
and returns a new
Functor
. In the process, it provides a monadic structure over f
.
hmap
lets us turn a
into a Free
f
: a monad built over
Free
gf
can be turned into a monad built over g
.
For the ability to move in and out of the enhanced functor, see
Inject
and Interpret
.
This class is similar to MFunctor
from
Control.Monad.Morph, but instances must work without a Monad
constraint.
This class is also found in the hschema library with the same name.
hmap :: (f ~> g) > t f ~> t g Source #
If we can turn an f
into a g
, then we can turn a t f
into
a t g
.
It must be the case that
hmap
id
== id
Essentially, t f
adds some "extra structure" to f
. hmap
must swap out the functor, without affecting the added structure.
For example,
is essentially a list of ListF
f af a
s. If we
hmap
to swap out the f a
s for g a
s, then we must ensure that
the "added structure" (here, the number of items in the list, and
the ordering of those items) remains the same. So, hmap
must
preserve the number of items in the list, and must maintain the
ordering.
The law
is a way of formalizing this property.hmap
id
== id
Instances
class HFunctor t => Inject t where Source #
A typeclass for HFunctor
s where you can "inject" an f a
into a t
f a
:
inject
:: f a > t f a
If you think of t f a
as an "enhanced f
", then inject
allows you
to use an f
as its enhanced form.
With the exception of directly pattern matching on the result, inject
itself is not too useful in the general case without
Interpret
to allow us to interpret or retrieve
back the f
.
Lift from f
into the enhanced t f
structure. Analogous to
lift
from MonadTrans
.
Note that this lets us "lift" a f a
; if you want to lift an a
with a > t f a
, check if t f
is an instance of Applicative
or
Pointed
.
Instances
class Inject t => Interpret t f where Source #
An Interpret
lets us move in and out of the "enhanced" Functor
(t
f
) and the functor it enhances (f
). An instance
means we have Interpret
t ft f a > f a
.
For example,
is Free
ff
enhanced with monadic structure. We get:
inject
:: f a >Free
f ainterpret
::Monad
m => (forall x. f x > m x) >Free
f a > m a
inject
will let us use our f
inside the enhanced
.
Free
finterpret
will let us "extract" the f
from a
if
we can give an interpreting function that interprets Free
ff
into some
target Monad
.
We enforce that:
interpret
id .inject
== id  orretract
.inject
== id
That is, if we lift a value into our structure, then immediately interpret it out as itself, it should lave the value unchanged.
Note that instances of this class are intended to be written with t
as a fixed type constructor, and f
to be allowed to vary freely:
instance Monad f => Interpret Free f
Any other sort of instance and it's easy to run into problems with type
inference. If you want to write an instance that's "polymorphic" on
tensor choice, use the WrapHF
newtype wrapper over a type variable,
where the second argument also uses a type constructor:
instance Interpret (WrapHF t) (MyFunctor t)
This will prevent problems with overloaded instances.
Remove the f
out of the enhanced t f
structure, provided that
f
satisfies the necessary constraints. If it doesn't, it needs to
be properly interpret
ed out.
interpret :: (g ~> f) > t g ~> f Source #
Given an "interpeting function" from f
to g
, interpret the f
out of the t f
into a final context g
.
Instances
Decide f => Interpret Dec1 (f :: Type > Type) Source #  
Conclude f => Interpret Dec (f :: Type > Type) Source #  
Apply f => Interpret Ap1 (f :: Type > Type) Source #  
Interpret (Reverse :: (k > Type) > k > Type) (f :: k > Type) Source #  
Interpret (Backwards :: (k > Type) > k > Type) (f :: k > Type) Source #  
Interpret (IdentityT :: (k > Type) > k > Type) (f :: k > Type) Source #  
Interpret (Flagged :: (k > Type) > k > Type) (f :: k > Type) Source #  
Interpret (Step :: (k > Type) > k > Type) (f :: k > Type) Source #  
(HBifunctor t, SemigroupIn t f) => Interpret (Chain1 t :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
Interpret t f => Interpret (HFree t :: (k > Type) > k > Type) (f :: k > Type) Source #  Never uses 
Interpret t f => Interpret (HLift t :: (k > Type) > k > Type) (f :: k > Type) Source #  Never uses 
c f => Interpret (Final c :: (k > Type) > k > Type) (f :: k > Type) Source #  
Interpret (M1 i c :: (k > Type) > k > Type) (f :: k > Type) Source #  
Interpret (RightF g :: (k2 > Type) > k2 > Type) (f :: k2 > Type) Source #  
MonoidIn t i f => Interpret (Chain t i :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  We can collapse and interpret an 
Applicative f => Interpret Ap (f :: Type > Type) Source #  A free 
Applicative f => Interpret Ap (f :: Type > Type) Source #  A free 
Applicative f => Interpret Ap (f :: Type > Type) Source #  A free 
Alternative f => Interpret Alt (f :: Type > Type) Source #  A free 
Functor f => Interpret Coyoneda (f :: Type > Type) Source #  A free 
Contravariant f => Interpret Coyoneda (f :: Type > Type) Source #  A free Since: 0.3.0.0 
Interpret WrappedApplicative (f :: Type > Type) Source #  
Defined in Data.HFunctor.Interpret  
Pointed f => Interpret MaybeApply (f :: Type > Type) Source #  A free 
Defined in Data.HFunctor.Interpret  
Pointed f => Interpret Lift (f :: Type > Type) Source #  A free 
Bind f => Interpret Free1 (f :: Type > Type) Source #  A free 
Monad f => Interpret Free (f :: Type > Type) Source #  A free 
Divise f => Interpret Div1 (f :: Type > Type) Source #  
Divisible f => Interpret Div (f :: Type > Type) Source #  
Monoid e => Interpret (EnvT e :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
MonadReader r f => Interpret (ReaderT r :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  A free 
Plus f => Interpret (These1 g :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  Technically, 
Alt f => Interpret (Steps :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
Plus f => Interpret (ListF :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  A free 
Alt f => Interpret (NonEmptyF :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  A free 
Plus f => Interpret (MaybeF :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  Technically, 
Interpret t f => Interpret (PostT t :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  Since: 0.3.4.2 
Interpret t f => Interpret (PreT t :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
Monoid a => Interpret (Post a :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
a ~ Void => Interpret (Pre a :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
Plus f => Interpret ((:+:) g :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  Technically, 
Plus g => Interpret ((:*:) g :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
Plus g => Interpret (Product g :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
Plus f => Interpret (Sum g :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  Technically, 
(Interpret s f, Interpret t f) => Interpret (ComposeT s t :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
(Monoid k, Plus f) => Interpret (MapF k :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
(Monoid k, Alt f) => Interpret (NEMapF k :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
forI :: Interpret t f => t g a > (g ~> f) > f a Source #
A convenient flipped version of interpret
.
iget :: Interpret t (AltConst b) => (forall x. f x > b) > t f a > b Source #
Useful wrapper over interpret
to allow you to directly extract
a value b
out of the t f a
, if you can convert f x
into b
.
Note that depending on the constraints on f
in
, you
may have extra constraints on Interpret
t fb
.
 If
f
is unconstrained, there are no constraints onb
 If
f
must beApply
,Alt
,Divise
, orDecide
,b
needs to be an instance ofSemigroup
.  If
f
isApplicative
,Plus
,Divisible
, orConclude
,b
needs to be an instance ofMonoid
For some constraints (like Monad
), this will not be usable.
 get the length of theMap String
in theStep
.icollect
length :: Step (Map String) Bool > Int
Since: 0.3.1.0
icollect :: (forall m. Monoid m => Interpret t (AltConst m)) => (forall x. f x > b) > t f a > [b] Source #
Useful wrapper over iget
to allow you to collect a b
from all
instances of f
inside a t f a
.
Will work if there is an instance of
if Interpret
t (AltConst
m)
, which will be the case if the constraint on the target
functor is Monoid
mFunctor
, Apply
, Applicative
, Alt
, Plus
,
Decide
, Divisible
, Decide
,
Conclude
, or unconstrained.
 get the lengths of allMap String
s in theAp
.icollect
length :: Ap (Map String) Bool > [Int]
Since: 0.3.1.0
icollect1 :: (forall m. Semigroup m => Interpret t (AltConst m)) => (forall x. f x > b) > t f a > NonEmpty b Source #
Useful wrapper over iget
to allow you to collect a b
from all
instances of f
inside a t f a
, into a nonempty collection of b
s.
Will work if there is an instance of
if
Interpret
t (AltConst
m)
, which will be the case if the constraint on the target
functor is Semigroup
mFunctor
, Apply
, Alt
, Divise
, Decide
, or
unconstrained.
 get the lengths of allMap String
s in theAp
.icollect1
length :: Ap1 (Map String) Bool >NonEmpty
Int
Since: 0.3.1.0
iapply :: Interpret t (Op b) => (forall x. f x > x > b) > t f a > a > b Source #
Useful wrapper over interpret
to allow you to directly consume
a value of type a
with a t f a
to create a b
. Do this by
supplying the method by which each component f x
can consume an x
.
This works for contravariant functor combinators, where t f a
can be
interpreted as a consumer of a
s.
Note that depending on the constraints on f
in
, you
may have extra constraints on Interpret
t fb
.
 If
f
is unconstrained,Decide
, orConclude
, there are no constraints onb
. This will be the case for combinators like contravariantCoyoneda
,Dec
,Dec1
.  If
f
must beDivise
,b
needs to be an instance ofSemigroup
. This will be the case for combinators likeDiv1
.  If
f
isDivisible
,b
needs to be an instance ofMonoid
. This will be the case for combinators likeDiv
.
For any Functor
or Invariant
constraint, this is not usable.
Since: 0.3.2.0
ifanout :: (forall m. Monoid m => Interpret t (Op m)) => (forall x. f x > x > b) > t f a > a > [b] Source #
Useful wrapper over interpret
to allow you to directly consume
a value of type a
with a t f a
to create a b
, and create a list of
all the b
s created by all the f
s. Do this by supplying the method
by which each component f x
can consume an x
. This works for
contravariant functor combinators, where t f a
can be interpreted as
a consumer of a
s.
Will work if there is an instance of
if Interpret
t (Op
m)
, which will be the case if the constraint on the target
functor is Monoid
mContravariant
, Decide
, Conclude
, Divise
, Divisible
,
or unconstrained.
Note that this is really only useful outside of iapply
for Div
and
Div1
, where a
which is a collection of many different Div
ff
s
consuming types of different values. You can use this with Dec
and
Dec1
and the contravarient Coyoneda
as well, but those would
always just give you a singleton list, so you might as well use
iapply
. This is really only here for completion alongside icollect
,
or if you define your own custom functor combinators.
ifanout1 :: (forall m. Semigroup m => Interpret t (Op m)) => (forall x. f x > x > b) > t f a > a > NonEmpty b Source #
Useful wrapper over interpret
to allow you to directly consume
a value of type a
with a t f a
to create a b
, and create a list of
all the b
s created by all the f
s. Do this by supplying the method
by which each component f x
can consume an x
. This works for
contravariant functor combinators, where t f a
can be interpreted as
a consumer of a
s.
Will work if there is an instance of
if Interpret
t (Op
m)
, which will be the case if the constraint on the target
functor is Monoid
mContravariant
, Decide
, Divise
, or unconstrained.
Note that this is really only useful outside of iapply
and ifanout
for Div1
, where a
which is a collection of many different
Div1
ff
s consuming types of different values. You can use this with Dec
and Dec1
and the contravarient Coyoneda
as well, but those would
always just give you a singleton list, so you might as well use
iapply
. This is really only here for completion alongside
icollect1
, or if you define your own custom functor combinators.
getI :: Interpret t (AltConst b) => (forall x. f x > b) > t f a > b Source #
Deprecated: Use iget instead
(Deprecated) Old name for getI
; will be removed in a future
version.
collectI :: (forall m. Monoid m => Interpret t (AltConst m)) => (forall x. f x > b) > t f a > [b] Source #
Deprecated: Use icollect instead
(Deprecated) Old name for icollect
; will be removed in a future
version.
injectMap :: (Inject t, Functor f) => (a > b) > f a > t f b Source #
A useful wrapper over the common pattern of fmapbeforeinject/injectandfmap.
Since: 0.3.3.0
injectContramap :: (Inject t, Contravariant f) => (a > b) > f b > t f a Source #
A useful wrapper over the common pattern of contramapbeforeinject/injectandcontramap.
Since: 0.3.3.0
A version of Const
that supports Alt
, Plus
, Decide
, and
Conclude
instances. It does this
by avoiding having an Alternative
or Decidable
instance, which
causes all sorts of problems with the interactions between
Alternative
/Applicative
and
Decidable
/Divisible
.
Since: 0.3.1.0
AltConst  

Instances
Functor (AltConst w :: Type > Type) Source #  
Monoid w => Applicative (AltConst w :: Type > Type) Source #  
Defined in Data.HFunctor.Interpret  
Foldable (AltConst w :: Type > Type) Source #  
Defined in Data.HFunctor.Interpret fold :: Monoid m => AltConst w m > m # foldMap :: Monoid m => (a > m) > AltConst w a > m # foldMap' :: Monoid m => (a > m) > AltConst w a > m # foldr :: (a > b > b) > b > AltConst w a > b # foldr' :: (a > b > b) > b > AltConst w a > b # foldl :: (b > a > b) > b > AltConst w a > b # foldl' :: (b > a > b) > b > AltConst w a > b # foldr1 :: (a > a > a) > AltConst w a > a # foldl1 :: (a > a > a) > AltConst w a > a # toList :: AltConst w a > [a] # null :: AltConst w a > Bool # length :: AltConst w a > Int # elem :: Eq a => a > AltConst w a > Bool # maximum :: Ord a => AltConst w a > a # minimum :: Ord a => AltConst w a > a #  
Traversable (AltConst w :: Type > Type) Source #  
Defined in Data.HFunctor.Interpret  
Contravariant (AltConst w :: Type > Type) Source #  
Eq w => Eq1 (AltConst w :: Type > Type) Source #  
Ord w => Ord1 (AltConst w :: Type > Type) Source #  
Defined in Data.HFunctor.Interpret  
Show w => Show1 (AltConst w :: Type > Type) Source #  
Monoid w => Divisible (AltConst w :: Type > Type) Source #  
Invariant (AltConst w :: Type > Type) Source #  
Defined in Data.HFunctor.Interpret  
Semigroup w => Apply (AltConst w :: Type > Type) Source #  
Monoid w => Plus (AltConst w :: Type > Type) Source #  Unlike for 
Defined in Data.HFunctor.Interpret  
Semigroup w => Alt (AltConst w :: Type > Type) Source #  Unlike for 
Semigroup w => Divise (AltConst w :: Type > Type) Source #  
Semigroup w => Decide (AltConst w :: Type > Type) Source #  Unlike for 
Monoid w => Conclude (AltConst w :: Type > Type) Source #  Unlike for 
Eq w => Eq (AltConst w a) Source #  
(Typeable a, Typeable k, Data w) => Data (AltConst w a) Source #  
Defined in Data.HFunctor.Interpret gfoldl :: (forall d b. Data d => c (d > b) > d > c b) > (forall g. g > c g) > AltConst w a > c (AltConst w a) # gunfold :: (forall b r. Data b => c (b > r) > c r) > (forall r. r > c r) > Constr > c (AltConst w a) # toConstr :: AltConst w a > Constr # dataTypeOf :: AltConst w a > DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) > Maybe (c (AltConst w a)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) > Maybe (c (AltConst w a)) # gmapT :: (forall b. Data b => b > b) > AltConst w a > AltConst w a # gmapQl :: (r > r' > r) > r > (forall d. Data d => d > r') > AltConst w a > r # gmapQr :: forall r r'. (r' > r > r) > r > (forall d. Data d => d > r') > AltConst w a > r # gmapQ :: (forall d. Data d => d > u) > AltConst w a > [u] # gmapQi :: Int > (forall d. Data d => d > u) > AltConst w a > u # gmapM :: Monad m => (forall d. Data d => d > m d) > AltConst w a > m (AltConst w a) # gmapMp :: MonadPlus m => (forall d. Data d => d > m d) > AltConst w a > m (AltConst w a) # gmapMo :: MonadPlus m => (forall d. Data d => d > m d) > AltConst w a > m (AltConst w a) #  
Ord w => Ord (AltConst w a) Source #  
Defined in Data.HFunctor.Interpret  
Show w => Show (AltConst w a) Source #  
Generic (AltConst w a) Source #  
type Rep (AltConst w a) Source #  
Defined in Data.HFunctor.Interpret 
MultiFunctors
Classes that deal with twofunctor combinators, that "mix" two functors together in some way.
class HBifunctor (t :: (k > Type) > (k > Type) > k > Type) where Source #
A HBifunctor
is like an HFunctor
, but it enhances two different
functors instead of just one.
Usually, it enhaces them "together" in some sort of combining way.
This typeclass provides a uniform instance for "swapping out" or
"hoisting" the enhanced functors. We can hoist the first one with
hleft
, the second one with hright
, or both at the same time with
hbimap
.
For example, the f :*: g
type gives us "both f
and g
":
data (f :*:
g) a = f a :*: g a
It combines both f
and g
into a unified structure  here, it does
it by providing both f
and g
.
The single law is:
hbimap
id
id == id
This ensures that hleft
, hright
, and hbimap
do not affect the
structure that t
adds on top of the underlying functors.
hleft :: (f ~> j) > t f g ~> t j g Source #
Swap out the first transformed functor.
hright :: (g ~> l) > t f g ~> t f l Source #
Swap out the second transformed functor.
hbimap :: (f ~> j) > (g ~> l) > t f g ~> t j l Source #
Swap out both transformed functors at the same time.
Instances
HBifunctor Night Source #  Since: 0.3.0.0 
Defined in Data.HFunctor.Internal hleft :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type). (f ~> j) > Night f g ~> Night j g Source # hright :: forall (g :: k > Type) (l :: k > Type) (f :: k > Type). (g ~> l) > Night f g ~> Night f l Source # hbimap :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type) (l :: k > Type). (f ~> j) > (g ~> l) > Night f g ~> Night j l Source #  
HBifunctor Night Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type). (f ~> j) > Night f g ~> Night j g Source # hright :: forall (g :: k > Type) (l :: k > Type) (f :: k > Type). (g ~> l) > Night f g ~> Night f l Source # hbimap :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type) (l :: k > Type). (f ~> j) > (g ~> l) > Night f g ~> Night j l Source #  
HBifunctor (Sum :: (k > Type) > (k > Type) > k > Type) Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type). (f ~> j) > Sum f g ~> Sum j g Source # hright :: forall (g :: k0 > Type) (l :: k0 > Type) (f :: k0 > Type). (g ~> l) > Sum f g ~> Sum f l Source # hbimap :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type) (l :: k0 > Type). (f ~> j) > (g ~> l) > Sum f g ~> Sum j l Source #  
HBifunctor ((:+:) :: (k > Type) > (k > Type) > k > Type) Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type). (f ~> j) > (f :+: g) ~> (j :+: g) Source # hright :: forall (g :: k0 > Type) (l :: k0 > Type) (f :: k0 > Type). (g ~> l) > (f :+: g) ~> (f :+: l) Source # hbimap :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type) (l :: k0 > Type). (f ~> j) > (g ~> l) > (f :+: g) ~> (j :+: l) Source #  
HBifunctor (Product :: (k > Type) > (k > Type) > k > Type) Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type). (f ~> j) > Product f g ~> Product j g Source # hright :: forall (g :: k0 > Type) (l :: k0 > Type) (f :: k0 > Type). (g ~> l) > Product f g ~> Product f l Source # hbimap :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type) (l :: k0 > Type). (f ~> j) > (g ~> l) > Product f g ~> Product j l Source #  
HBifunctor ((:*:) :: (k > Type) > (k > Type) > k > Type) Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type). (f ~> j) > (f :*: g) ~> (j :*: g) Source # hright :: forall (g :: k0 > Type) (l :: k0 > Type) (f :: k0 > Type). (g ~> l) > (f :*: g) ~> (f :*: l) Source # hbimap :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type) (l :: k0 > Type). (f ~> j) > (g ~> l) > (f :*: g) ~> (j :*: l) Source #  
HBifunctor (Joker :: (k > Type) > (k > Type) > k > Type) Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type). (f ~> j) > Joker f g ~> Joker j g Source # hright :: forall (g :: k0 > Type) (l :: k0 > Type) (f :: k0 > Type). (g ~> l) > Joker f g ~> Joker f l Source # hbimap :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type) (l :: k0 > Type). (f ~> j) > (g ~> l) > Joker f g ~> Joker j l Source #  
HBifunctor (LeftF :: (k > Type) > (k > Type) > k > Type) Source #  
Defined in Data.HBifunctor hleft :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type). (f ~> j) > LeftF f g ~> LeftF j g Source # hright :: forall (g :: k0 > Type) (l :: k0 > Type) (f :: k0 > Type). (g ~> l) > LeftF f g ~> LeftF f l Source # hbimap :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type) (l :: k0 > Type). (f ~> j) > (g ~> l) > LeftF f g ~> LeftF j l Source #  
HBifunctor (RightF :: (k > Type) > (k > Type) > k > Type) Source #  
Defined in Data.HBifunctor hleft :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type). (f ~> j) > RightF f g ~> RightF j g Source # hright :: forall (g :: k0 > Type) (l :: k0 > Type) (f :: k0 > Type). (g ~> l) > RightF f g ~> RightF f l Source # hbimap :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type) (l :: k0 > Type). (f ~> j) > (g ~> l) > RightF f g ~> RightF j l Source #  
HBifunctor (Void3 :: (k > Type) > (k > Type) > k > Type) Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type). (f ~> j) > Void3 f g ~> Void3 j g Source # hright :: forall (g :: k0 > Type) (l :: k0 > Type) (f :: k0 > Type). (g ~> l) > Void3 f g ~> Void3 f l Source # hbimap :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type) (l :: k0 > Type). (f ~> j) > (g ~> l) > Void3 f g ~> Void3 j l Source #  
HBifunctor t => HBifunctor (WrapHBF t :: (k > Type) > (k > Type) > k > Type) Source #  
Defined in Data.HBifunctor.Associative hleft :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type). (f ~> j) > WrapHBF t f g ~> WrapHBF t j g Source # hright :: forall (g :: k0 > Type) (l :: k0 > Type) (f :: k0 > Type). (g ~> l) > WrapHBF t f g ~> WrapHBF t f l Source # hbimap :: forall (f :: k0 > Type) (j :: k0 > Type) (g :: k0 > Type) (l :: k0 > Type). (f ~> j) > (g ~> l) > WrapHBF t f g ~> WrapHBF t j l Source #  
HBifunctor Day Source #  Since: 0.3.4.0 
Defined in Data.HFunctor.Internal hleft :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type). (f ~> j) > Day f g ~> Day j g Source # hright :: forall (g :: k > Type) (l :: k > Type) (f :: k > Type). (g ~> l) > Day f g ~> Day f l Source # hbimap :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type) (l :: k > Type). (f ~> j) > (g ~> l) > Day f g ~> Day j l Source #  
HBifunctor Day Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type). (f ~> j) > Day f g ~> Day j g Source # hright :: forall (g :: k > Type) (l :: k > Type) (f :: k > Type). (g ~> l) > Day f g ~> Day f l Source # hbimap :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type) (l :: k > Type). (f ~> j) > (g ~> l) > Day f g ~> Day j l Source #  
HBifunctor Day Source #  Since: 0.3.0.0 
Defined in Data.HFunctor.Internal hleft :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type). (f ~> j) > Day f g ~> Day j g Source # hright :: forall (g :: k > Type) (l :: k > Type) (f :: k > Type). (g ~> l) > Day f g ~> Day f l Source # hbimap :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type) (l :: k > Type). (f ~> j) > (g ~> l) > Day f g ~> Day j l Source #  
HBifunctor These1 Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type). (f ~> j) > These1 f g ~> These1 j g Source # hright :: forall (g :: k > Type) (l :: k > Type) (f :: k > Type). (g ~> l) > These1 f g ~> These1 f l Source # hbimap :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type) (l :: k > Type). (f ~> j) > (g ~> l) > These1 f g ~> These1 j l Source #  
HBifunctor (Comp :: (Type > Type) > (Type > Type) > Type > Type) Source #  
Defined in Data.HFunctor.Internal hleft :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type). (f ~> j) > Comp f g ~> Comp j g Source # hright :: forall (g :: k > Type) (l :: k > Type) (f :: k > Type). (g ~> l) > Comp f g ~> Comp f l Source # hbimap :: forall (f :: k > Type) (j :: k > Type) (g :: k > Type) (l :: k > Type). (f ~> j) > (g ~> l) > Comp f g ~> Comp j l Source # 
Associative
class (HBifunctor t, Inject (NonEmptyBy t)) => Associative t where Source #
An HBifunctor
where it doesn't matter which binds first is
Associative
. Knowing this gives us a lot of power to rearrange the
internals of our HFunctor
at will.
For example, for the functor product:
data (f :*:
g) a = f a :*: g a
We know that f :*: (g :*: h)
is the same as (f :*: g) :*: h
.
Formally, we can say that t
enriches a the category of
endofunctors with semigroup strcture: it turns our endofunctor category
into a "semigroupoidal category".
Different instances of t
each enrich the endofunctor category in
different ways, giving a different semigroupoidal category.
type NonEmptyBy t :: (Type > Type) > Type > Type Source #
The "semigroup functor combinator" generated by t
.
A value of type NonEmptyBy t f a
is equivalent to one of:
f a
t f f a
t f (t f f) a
t f (t f (t f f)) a
t f (t f (t f (t f f))) a
 .. etc
For example, for :*:
, we have NonEmptyF
. This is because:
x ~NonEmptyF
(x:
[]) ~inject
x x:*:
y ~ NonEmptyF (x : [y]) ~toNonEmptyBy
(x :*: y) x :*: y :*: z ~ NonEmptyF (x : [y,z])  etc.
You can create an "singleton" one with inject
, or else one from
a single t f f
with toNonEmptyBy
.
See ListBy
for a "possibly empty" version
of this type.
type FunctorBy t :: (Type > Type) > Constraint Source #
A description of "what type of Functor" this tensor is expected to
be applied to. This should typically always be either Functor
,
Contravariant
, or Invariant
.
Since: 0.3.0.0
type FunctorBy t = Unconstrained Source #
associating :: (FunctorBy t f, FunctorBy t g, FunctorBy t h) => t f (t g h) <~> t (t f g) h Source #
The isomorphism between t f (t g h) a
and t (t f g) h a
. To
use this isomorphism, see assoc
and disassoc
.
appendNE :: t (NonEmptyBy t f) (NonEmptyBy t f) ~> NonEmptyBy t f Source #
If a
represents multiple applications of NonEmptyBy
t ft f
to
itself, then we can also "append" two
s applied to
themselves into one giant NonEmptyBy
t f
containing all of the NonEmptyBy
t ft f
s.
Note that this essentially gives an instance for
, for any functor SemigroupIn
t (NonEmptyBy t f)f
.
matchNE :: FunctorBy t f => NonEmptyBy t f ~> (f :+: t f (NonEmptyBy t f)) Source #
If a
represents multiple applications of NonEmptyBy
t ft f
to itself, then we can split it based on whether or not it is just
a single f
or at least one toplevel application of t f
.
Note that you can recursively "unroll" a NonEmptyBy
completely
into a Chain1
by using
unrollNE
.
consNE :: t f (NonEmptyBy t f) ~> NonEmptyBy t f Source #
Prepend an application of t f
to the front of a
.NonEmptyBy
t f
toNonEmptyBy :: t f f ~> NonEmptyBy t f Source #
Embed a direct application of f
to itself into a
.NonEmptyBy
t f
Instances
class (Associative t, FunctorBy t f) => SemigroupIn t f where Source #
For different
, we have functors Associative
tf
that we can
"squash", using biretract
:
t f f ~> f
This gives us the ability to squash applications of t
.
Formally, if we have
, we are enriching the category of
endofunctors with semigroup structure, turning it into a semigroupoidal
category. Different choices of Associative
tt
give different semigroupoidal
categories.
A functor f
is known as a "semigroup in the (semigroupoidal) category
of endofunctors on t
" if we can biretract
:
t f f ~> f
This gives us a few interesting results in category theory, which you can stil reading about if you don't care:
 All functors are semigroups in the semigroupoidal category
on
:+:
 The class of functors that are semigroups in the semigroupoidal
category on
:*:
is exactly the functors that are instances ofAlt
.  The class of functors that are semigroups in the semigroupoidal
category on
Day
is exactly the functors that are instances ofApply
.  The class of functors that are semigroups in the semigroupoidal
category on
Comp
is exactly the functors that are instances ofBind
.
Note that instances of this class are intended to be written with t
as a fixed type constructor, and f
to be allowed to vary freely:
instance Bind f => SemigroupIn Comp f
Any other sort of instance and it's easy to run into problems with type
inference. If you want to write an instance that's "polymorphic" on
tensor choice, use the WrapHBF
newtype wrapper over a type variable,
where the second argument also uses a type constructor:
instance SemigroupIn (WrapHBF t) (MyFunctor t i)
This will prevent problems with overloaded instances.
Nothing
biretract :: t f f ~> f Source #
The HBifunctor
analogy of retract
. It retracts both f
s
into a single f
, effectively fully mixing them together.
This function makes f
a semigroup in the category of endofunctors
with respect to tensor t
.
binterpret :: (g ~> f) > (h ~> f) > t g h ~> f Source #
The HBifunctor
analogy of interpret
. It takes two
interpreting functions, and mixes them together into a target
functor h
.
Note that this is useful in the polykinded case, but it is not possible
to define generically for all SemigroupIn
because it only is defined
for Type > Type
inputes. See !+!
for a version that is polykinded
for :+:
in specific.
default binterpret :: Interpret (NonEmptyBy t) f => (g ~> f) > (h ~> f) > t g h ~> f Source #
Instances
Apply f => SemigroupIn Day f Source #  Instances of 
Divise f => SemigroupIn Day f Source #  Since: 0.3.0.0 
Alt f => SemigroupIn These1 f Source #  
Decide f => SemigroupIn Night f Source #  Since: 0.3.0.0 
SemigroupIn ((:+:) :: (Type > Type) > (Type > Type) > Type > Type) f Source #  All functors are semigroups in the semigroupoidal category on 
Alt f => SemigroupIn ((:*:) :: (Type > Type) > (Type > Type) > Type > Type) f Source #  Instances of 
Alt f => SemigroupIn (Product :: (Type > Type) > (Type > Type) > Type > Type) f Source #  Instances of 
SemigroupIn (Sum :: (Type > Type) > (Type > Type) > Type > Type) f Source #  All functors are semigroups in the semigroupoidal category on 
Bind f => SemigroupIn (Comp :: (Type > Type) > (Type > Type) > Type > Type) f Source #  Instances of 
SemigroupIn (Joker :: (Type > Type) > (Type > Type) > Type > Type) f Source #  
SemigroupIn (LeftF :: (Type > Type) > (Type > Type) > Type > Type) f Source #  
SemigroupIn (RightF :: (Type > Type) > (Type > Type) > Type > Type) f Source #  
SemigroupIn (Void3 :: (Type > Type) > (Type > Type) > Type > Type) f Source #  All functors are semigroups in the semigroupoidal category on 
(Associative t, FunctorBy t f, FunctorBy t (WrapNE t f)) => SemigroupIn (WrapHBF t) (WrapNE t f) Source #  
(Tensor t i, FunctorBy t f, FunctorBy t (WrapLB t f)) => SemigroupIn (WrapHBF t) (WrapLB t f) Source #  
(Associative t, FunctorBy t f, FunctorBy t (Chain1 t f)) => SemigroupIn (WrapHBF t) (Chain1 t f) Source # 

(Tensor t i, FunctorBy t (Chain t i f)) => SemigroupIn (WrapHBF t) (Chain t i f) Source #  We have to wrap 
biget :: SemigroupIn t (AltConst b) => (forall x. f x > b) > (forall x. g x > b) > t f g a > b Source #
Useful wrapper over binterpret
to allow you to directly extract
a value b
out of the t f g a
, if you can convert an f x
and g x
into b
.
Note that depending on the constraints on h
in
,
you may have extra constraints on SemigroupIn
t hb
.
 If
h
is unconstrained, there are no constraints onb
 If
h
must beApply
,Alt
,Divise
, orDecide
,b
needs to be an instance ofSemigroup
 If
h
isApplicative
,Plus
,Divisible
, orConclude
,b
needs to be an instance ofMonoid
For some constraints (like Monad
), this will not be usable.
 Return the length of either the list, or the Map, depending on which  one s in the+
biget
length
length :: ([] :+:Map
Int
)Char
> Int  Return the length of both the list and the map, added togetherbiget
(Sum
. length) (Sum . length) ::Day
[] (Map Int) Char > Sum Int
biapply :: SemigroupIn t (Op b) => (forall x. f x > x > b) > (forall x. g x > x > b) > t f g a > a > b Source #
Useful wrapper over binterpret
to allow you to directly extract
a value b
out of the t f g a
, if you can convert an f x
and g x
into b
, given an x
input.
Note that depending on the constraints on h
in
,
you may have extra constraints on SemigroupIn
t hb
.
 If
h
is unconstrained, there are no constraints onb
 If
h
must beDivise
, orDivisible
,b
needs to be an instance ofSemigroup
 If
h
must beDivisible
, thenb
needs to be an instance ofMonoid
.
For some constraints (like Monad
), this will not be usable.
Since: 0.3.2.0
(!*!) :: SemigroupIn t h => (f ~> h) > (g ~> h) > t f g ~> h infixr 5 Source #
Infix alias for binterpret
Note that this is useful in the polykinded case, but it is not possible
to define generically for all SemigroupIn
because it only is defined
for Type > Type
inputes. See !+!
for a version that is polykinded
for :+:
in specific.
(!$!) :: SemigroupIn t (AltConst b) => (forall x. f x > b) > (forall x. g x > b) > t f g a > b infixr 5 Source #
Tensor
class (Associative t, Inject (ListBy t)) => Tensor t i  t > i where Source #
An Associative
HBifunctor
can be a Tensor
if there is some
identity i
where t i f
and t f i
are equivalent to just f
.
That is, "enhancing" f
with t i
does nothing.
The methods in this class provide us useful ways of navigating
a
with respect to this property.Tensor
t
The Tensor
is essentially the HBifunctor
equivalent of Inject
,
with intro1
and intro2
taking the place of inject
.
Formally, we can say that t
enriches a the category of
endofunctors with monoid strcture: it turns our endofunctor category
into a "monoidal category".
Different instances of t
each enrich the endofunctor category in
different ways, giving a different monoidal category.
type ListBy t :: (Type > Type) > Type > Type Source #
The "monoidal functor combinator" induced by t
.
A value of type ListBy t f a
is equivalent to one of:
I a
 zero fsf a
 one ft f f a
 two fst f (t f f) a
 three fst f (t f (t f f)) a
t f (t f (t f (t f f))) a
 .. etc
For example, for :*:
, we have ListF
. This is because:
Proxy
~ListF
[] ~nilLB
@(:*:
) x ~ ListF [x] ~inject
x x :*: y ~ ListF [x,y] ~toListBy
(x :*: y) x :*: y :*: z ~ ListF [x,y,z]  etc.
You can create an "empty" one with nilLB
, a "singleton" one with
inject
, or else one from a single t f f
with toListBy
.
See NonEmptyBy
for a "nonempty"
version of this type.
Because t f (I t)
is equivalent to f
, we can always "insert"
f
into t f (I t)
.
This is analogous to inject
from Inject
, but for HBifunctor
s.
Because t (I t) g
is equivalent to f
, we can always "insert"
g
into t (I t) g
.
This is analogous to inject
from Inject
, but for HBifunctor
s.
elim1 :: FunctorBy t f => t f i ~> f Source #
Witnesses the property that i
is the identity of t
: t
f i
always leaves f
unchanged, so we can always just drop the
i
.
elim2 :: FunctorBy t g => t i g ~> g Source #
Witnesses the property that i
is the identity of t
: t i g
always leaves g
unchanged, so we can always just drop the i t
.
appendLB :: t (ListBy t f) (ListBy t f) ~> ListBy t f Source #
If a
represents multiple applications of ListBy
t ft f
to
itself, then we can also "append" two
s applied to
themselves into one giant ListBy
t f
containing all of the ListBy
t ft f
s.
Note that this essentially gives an instance for
, for any functor SemigroupIn
t (ListBy t f)f
; this is witnessed by
WrapLB
.
splitNE :: NonEmptyBy t f ~> t f (ListBy t f) Source #
Lets you convert an
into a single application of NonEmptyBy
t ff
to
.ListBy
t f
Analogous to a function NonEmpty
a > (a,
[a])
Note that this is not reversible in general unless we have
.Matchable
t
splittingLB :: ListBy t f <~> (i :+: t f (ListBy t f)) Source #
An
is either empty, or a single application of ListBy
t ft
to f
and ListBy t f
(the "head" and "tail"). This witnesses that
isomorphism.
toListBy :: t f f ~> ListBy t f Source #
Embed a direct application of f
to itself into a
.ListBy
t f
fromNE :: NonEmptyBy t f ~> ListBy t f Source #
is "one or more NonEmptyBy
t ff
s", and 'ListBy t f
is "zero or more
f
s". This function lets us convert from one to the other.
This is analogous to a function
.NonEmpty
a >
[a]
Note that because t
is not inferrable from the input or output
type, you should call this using XTypeApplications:
fromNE
@(:*:
) ::NonEmptyF
f a >ListF
f a fromNE @Comp
::Free1
f a >Free
f a
Instances
class (Tensor t i, SemigroupIn t f) => MonoidIn t i f where Source #
This class effectively gives us a way to generate a value of f a
based on an i a
, for
. Having this ability makes a lot
of interesting functions possible when used with Tensor
t ibiretract
from
SemigroupIn
that weren't possible without it: it gives us a "base
case" for recursion in a lot of cases.
Essentially, we get an i ~> f
, pureT
, where we can introduce an f
a
as long as we have an i a
.
Formally, if we have
, we are enriching the category of
endofunctors with monoid structure, turning it into a monoidal category.
Different choices of Tensor
t it
give different monoidal categories.
A functor f
is known as a "monoid in the (monoidal) category
of endofunctors on t
" if we can biretract
:
t f f ~> f
and also pureT
:
i ~> f
This gives us a few interesting results in category theory, which you can stil reading about if you don't care:
 All functors are monoids in the monoidal category
on
:+:
 The class of functors that are monoids in the monoidal
category on
:*:
is exactly the functors that are instances ofPlus
.  The class of functors that are monoids in the monoidal
category on
Day
is exactly the functors that are instances ofApplicative
.  The class of functors that are monoids in the monoidal
category on
Comp
is exactly the functors that are instances ofMonad
.
This is the meaning behind the common adage, "monads are just monoids
in the category of endofunctors". It means that if you enrich the
category of endofunctors to be monoidal with Comp
, then the class
of functors that are monoids in that monoidal category are exactly
what monads are. However, the adage is a little misleading: there
are many other ways to enrich the category of endofunctors to be
monoidal, and Comp
is just one of them. Similarly, the class of
functors that are monoids in the category of endofunctors enriched by
Day
are Applicative
.
Note that instances of this class are intended to be written with t
and i
to be fixed type constructors, and f
to be allowed to vary
freely:
instance Monad f => MonoidIn Comp Identity f
Any other sort of instance and it's easy to run into problems with type
inference. If you want to write an instance that's "polymorphic" on
tensor choice, use the WrapHBF
and WrapF
newtype wrappers over type
variables, where the third argument also uses a type constructor:
instance MonoidIn (WrapHBF t) (WrapF i) (MyFunctor t i)
This will prevent problems with overloaded instances.
Nothing
If we have an i
, we can generate an f
based on how it
interacts with t
.
Specialized (and simplified), this type is:
pureT
@Day
::Applicative
f =>Identity
a > f a pure
pureT @Comp
::Monad
f => Identity a > f a return
pureT @(:*:
) ::Plus
f =>Proxy
a > f a zero
Note that because t
appears nowhere in the input or output types,
you must always use this with explicit type application syntax (like
pureT @Day
)
Along with biretract
, this function makes f
a monoid in the
category of endofunctors with respect to tensor t
.
Instances
(Apply f, Applicative f) => MonoidIn Day Identity f Source #  Instances of Note that because of typeclass constraints, this requires 
Conclude f => MonoidIn Night Not f Source #  Instances of 
(Divise f, Divisible f) => MonoidIn Day (Proxy :: Type > Type) f Source #  Instances of Note that because of typeclass constraints, this requires Since: 0.3.0.0 
Alt f => MonoidIn These1 (V1 :: Type > Type) f Source #  
(Bind f, Monad f) => MonoidIn (Comp :: (Type > Type) > (Type > Type) > Type > Type) Identity f Source #  Instances of This instance is the "proof" that "monads are the monoids in the
category of endofunctors (enriched with Note that because of typeclass constraints, this requires 
MonoidIn ((:+:) :: (Type > Type) > (Type > Type) > Type > Type) (V1 :: Type > Type) f Source #  All functors are monoids in the monoidal category on 
Plus f => MonoidIn ((:*:) :: (Type > Type) > (Type > Type) > Type > Type) (Proxy :: Type > Type) f Source #  Instances of 
Plus f => MonoidIn (Product :: (Type > Type) > (Type > Type) > Type > Type) (Proxy :: Type > Type) f Source #  Instances of 
MonoidIn (Sum :: (Type > Type) > (Type > Type) > Type > Type) (V1 :: Type > Type) f Source #  All functors are monoids in the monoidal category on 
(Tensor t i, FunctorBy t f, FunctorBy t (WrapLB t f)) => MonoidIn (WrapHBF t) (WrapF i) (WrapLB t f) Source #  
(Tensor t i, FunctorBy t (Chain t i f)) => MonoidIn (WrapHBF t) (WrapF i) (Chain t i f) Source # 

nilLB :: forall t i f. Tensor t i => i ~> ListBy t f Source #
Create the "empty ListBy
".
If
represents multiple applications of ListBy
t ft f
with
itself, then nilLB
gives us "zero applications of f
".
Note that t
cannot be inferred from the input or output type of
nilLB
, so this function must always be called with XTypeApplications:
nilLB
@Day
::Identity
~>
Ap
f nilLB @Comp
:: Identity ~>Free
f nilLB @(:*:
) ::Proxy
~>ListF
f
Note that this essentially gives an instance for
, for any functor MonoidIn
t i (ListBy
t f)f
; this is witnessed by WrapLB
.
consLB :: Tensor t i => t f (ListBy t f) ~> ListBy t f Source #
Lets us "cons" an application of f
to the front of an
.ListBy
t f
inL :: forall t i f g. MonoidIn t i g => f ~> t f g Source #
Convenient wrapper over intro1
that lets us introduce an arbitrary
functor g
to the right of an f
.
You can think of this as an HBifunctor
analogue of inject
.
inR :: forall t i f g. MonoidIn t i f => g ~> t f g Source #
Convenient wrapper over intro2
that lets us introduce an arbitrary
functor f
to the right of a g
.
You can think of this as an HBifunctor
analogue of inject
.
Combinators
Functor combinators ** Single
data Coyoneda (f :: Type > Type) a where #
A covariant Functor
suitable for Yoneda reduction
Instances
A list of f a
s. Can be used to describe a product of many different
values of type f a
.
This is the Free Plus
.
Incidentally, if used with a Contravariant
f
, this is instead the
free Divisible
.
Instances
HFunctor (ListF :: (k > Type) > k > Type) Source #  
HBind (ListF :: (k > Type) > k > Type) Source #  
Inject (ListF :: (k > Type) > k > Type) Source #  
FreeOf Plus (ListF :: (Type > Type) > Type > Type) Source #  This could also be 
Plus f => Interpret (ListF :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  A free 
Functor f => Functor (ListF f) Source #  
Applicative f => Applicative (ListF f) Source #  
Foldable f => Foldable (ListF f) Source #  
Defined in Control.Applicative.ListF fold :: Monoid m => ListF f m > m # foldMap :: Monoid m => (a > m) > ListF f a > m # foldMap' :: Monoid m => (a > m) > ListF f a > m # foldr :: (a > b > b) > b > ListF f a > b # foldr' :: (a > b > b) > b > ListF f a > b # foldl :: (b > a > b) > b > ListF f a > b # foldl' :: (b > a > b) > b > ListF f a > b # foldr1 :: (a > a > a) > ListF f a > a # foldl1 :: (a > a > a) > ListF f a > a # elem :: Eq a => a > ListF f a > Bool # maximum :: Ord a => ListF f a > a # minimum :: Ord a => ListF f a > a #  
Traversable f => Traversable (ListF f) Source #  
Defined in Control.Applicative.ListF traverse :: Applicative f0 => (a > f0 b) > ListF f a > f0 (ListF f b) # sequenceA :: Applicative f0 => 