Copyright  (c) Justin Le 2019 

License  BSD3 
Maintainer  justin@jle.im 
Stability  experimental 
Portability  nonportable 
Safe Haskell  None 
Language  Haskell2010 
This module provides an Interpret
able data type of "linked list of
tensor applications".
The type
, for any Chain
t
, is meant to be the same as
Tensor
t
(the monoidal functor combinator for ListBy
tt
), and represents
"zero or more" applications of f
to t
.
The type
, for any Chain1
t
, is meant to be the
same as Associative
t
(the semigroupoidal functor combinator for NonEmptyBy
tt
) and
represents "one or more" applications of f
to t
.
The advantage of using Chain
and Chain1
over ListBy
or NonEmptyBy
is that
they provide a universal interface for pattern matching and constructing
such values, which may simplify working with new such functor
combinators you might encounter.
Synopsis
 data Chain t i f a
 foldChain :: forall t i f g. HBifunctor t => (i ~> g) > (t f g ~> g) > Chain t i f ~> g
 unfoldChain :: forall t f (g :: Type > Type) i. HBifunctor t => (g ~> (i :+: t f g)) > g ~> Chain t i f
 unroll :: Tensor t i => ListBy t f ~> Chain t i f
 reroll :: forall t i f. Tensor t i => Chain t i f ~> ListBy t f
 unrolling :: Tensor t i => ListBy t f <~> Chain t i f
 appendChain :: forall t i f. Tensor t i => t (Chain t i f) (Chain t i f) ~> Chain t i f
 data Chain1 t f a
 foldChain1 :: forall t f g. HBifunctor t => (f ~> g) > (t f g ~> g) > Chain1 t f ~> g
 unfoldChain1 :: forall t f (g :: Type > Type). HBifunctor t => (g ~> (f :+: t f g)) > g ~> Chain1 t f
 unrollingNE :: forall t f. (Associative t, Functor f) => NonEmptyBy t f <~> Chain1 t f
 unrollNE :: (Associative t, Functor f) => NonEmptyBy t f ~> Chain1 t f
 rerollNE :: Associative t => Chain1 t f ~> NonEmptyBy t f
 appendChain1 :: forall t f. (Associative t, Functor f) => t (Chain1 t f) (Chain1 t f) ~> Chain1 t f
 fromChain1 :: Tensor t i => Chain1 t f ~> Chain t i f
 splittingChain1 :: forall t i f. (Matchable t i, Functor f) => Chain1 t f <~> t f (Chain t i f)
 splitChain1 :: forall t i f. Tensor t i => Chain1 t f ~> t f (Chain t i f)
 matchingChain :: forall t i f. (Tensor t i, Matchable t i, Functor f) => Chain t i f <~> (i :+: Chain1 t f)
 unmatchChain :: forall t i f. Tensor t i => (i :+: Chain1 t f) ~> Chain t i f
Chain
A useful construction that works like a "linked list" of t f
applied
to itself multiple times. That is, it contains t f f
, t f (t f f)
,
t f (t f (t f f))
, etc, with f
occuring zero or more times. It is
meant to be the same as
.ListBy
t
If t
is Tensor
, then it means we can "collapse" this linked list
into some final type
(ListBy
treroll
), and also extract it back
into a linked list (unroll
).
So, a value of type
is one of either:Chain
t i f a
i a
f a
t f f a
t f (t f f) a
t f (t f (t f f)) a
 .. etc.
Note that this is exactly what an
is supposed to be. Using
ListBy
tChain
allows us to work with all
s in a uniform way, with
normal pattern matching and normal constructors.ListBy
t
You can fully "collapse" a
into an Chain
t i ff
with
retract
, if you have
; this could be considered
a fundamental property of monoidness.MonoidIn
t i f
Another way of thinking of this is that
is the "free
Chain
t i
". Given any functor MonoidIn
t if
,
is a monoid
in the monoidal category of endofunctors enriched by Chain
t i ft
. So,
is
the "free Chain
Comp
Identity
Monad
",
is the "free Chain
Day
Identity
Applicative
", etc. You
"lift" from f a
to
using Chain
t i f ainject
.
Note: this instance doesn't exist directly because of restrictions in typeclasses, but is implemented as
Tensor
t i =>MonoidIn
(WrapHBF
t) (WrapF
i) (Chain
t i f)
where pureT
is Done
and biretract
is appendChain
.
This construction is inspired by http://oleg.fi/gists/posts/20180221singlefree.html
Instances
HBifunctor t => HFunctor (Chain t i :: (k > Type) > k > Type) Source #  
Tensor t i => Inject (Chain t i :: (Type > Type) > Type > Type) Source #  
MonoidIn t i f => Interpret (Chain t i :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  We can collapse and interpret an 
(Tensor t i, Functor f) => MonoidIn (WrapHBF t) (WrapF i) (Chain t i f) Source # 

(Tensor t i, Functor f) => SemigroupIn (WrapHBF t) (Chain t i f) Source #  We have to wrap 
Monad (Chain (Comp :: (Type > Type) > (Type > Type) > Type > Type) Identity f) Source # 

(Functor i, Functor (t f (Chain t i f))) => Functor (Chain t i f) Source #  
Applicative (Chain Day Identity f) Source # 

Defined in Data.HFunctor.Chain pure :: a > Chain Day Identity f a # (<*>) :: Chain Day Identity f (a > b) > Chain Day Identity f a > Chain Day Identity f b # liftA2 :: (a > b > c) > Chain Day Identity f a > Chain Day Identity f b > Chain Day Identity f c # (*>) :: Chain Day Identity f a > Chain Day Identity f b > Chain Day Identity f b # (<*) :: Chain Day Identity f a > Chain Day Identity f b > Chain Day Identity f a #  
Applicative (Chain (Comp :: (Type > Type) > (Type > Type) > Type > Type) Identity f) Source #  
Defined in Data.HFunctor.Chain pure :: a > Chain Comp Identity f a # (<*>) :: Chain Comp Identity f (a > b) > Chain Comp Identity f a > Chain Comp Identity f b # liftA2 :: (a > b > c) > Chain Comp Identity f a > Chain Comp Identity f b > Chain Comp Identity f c # (*>) :: Chain Comp Identity f a > Chain Comp Identity f b > Chain Comp Identity f b # (<*) :: Chain Comp Identity f a > Chain Comp Identity f b > Chain Comp Identity f a #  
(Foldable i, Foldable (t f (Chain t i f))) => Foldable (Chain t i f) Source #  
Defined in Data.HFunctor.Chain fold :: Monoid m => Chain t i f m > m # foldMap :: Monoid m => (a > m) > Chain t i f a > m # foldr :: (a > b > b) > b > Chain t i f a > b # foldr' :: (a > b > b) > b > Chain t i f a > b # foldl :: (b > a > b) > b > Chain t i f a > b # foldl' :: (b > a > b) > b > Chain t i f a > b # foldr1 :: (a > a > a) > Chain t i f a > a # foldl1 :: (a > a > a) > Chain t i f a > a # toList :: Chain t i f a > [a] # null :: Chain t i f a > Bool # length :: Chain t i f a > Int # elem :: Eq a => a > Chain t i f a > Bool # maximum :: Ord a => Chain t i f a > a # minimum :: Ord a => Chain t i f a > a #  
(Traversable i, Traversable (t f (Chain t i f))) => Traversable (Chain t i f) Source #  
Defined in Data.HFunctor.Chain  
(Eq1 i, Eq1 (t f (Chain t i f))) => Eq1 (Chain t i f) Source #  
(Ord1 i, Ord1 (t f (Chain t i f))) => Ord1 (Chain t i f) Source #  
Defined in Data.HFunctor.Chain  
(Functor i, Read1 (t f (Chain t i f)), Read1 i) => Read1 (Chain t i f) Source #  
Defined in Data.HFunctor.Chain liftReadsPrec :: (Int > ReadS a) > ReadS [a] > Int > ReadS (Chain t i f a) # liftReadList :: (Int > ReadS a) > ReadS [a] > ReadS [Chain t i f a] # liftReadPrec :: ReadPrec a > ReadPrec [a] > ReadPrec (Chain t i f a) # liftReadListPrec :: ReadPrec a > ReadPrec [a] > ReadPrec [Chain t i f a] #  
(Show1 (t f (Chain t i f)), Show1 i) => Show1 (Chain t i f) Source #  
Apply (Chain Day Identity f) Source #  
Defined in Data.HFunctor.Chain (<.>) :: Chain Day Identity f (a > b) > Chain Day Identity f a > Chain Day Identity f b # (.>) :: Chain Day Identity f a > Chain Day Identity f b > Chain Day Identity f b # (<.) :: Chain Day Identity f a > Chain Day Identity f b > Chain Day Identity f a # liftF2 :: (a > b > c) > Chain Day Identity f a > Chain Day Identity f b > Chain Day Identity f c #  
Apply (Chain (Comp :: (Type > Type) > (Type > Type) > Type > Type) Identity f) Source #  
Defined in Data.HFunctor.Chain (<.>) :: Chain Comp Identity f (a > b) > Chain Comp Identity f a > Chain Comp Identity f b # (.>) :: Chain Comp Identity f a > Chain Comp Identity f b > Chain Comp Identity f b # (<.) :: Chain Comp Identity f a > Chain Comp Identity f b > Chain Comp Identity f a # liftF2 :: (a > b > c) > Chain Comp Identity f a > Chain Comp Identity f b > Chain Comp Identity f c #  
Functor f => Plus (Chain ((:*:) :: (Type > Type) > (Type > Type) > Type > Type) (Proxy :: Type > Type) f) Source # 

Functor f => Plus (Chain (Product :: (Type > Type) > (Type > Type) > Type > Type) (Proxy :: Type > Type) f) Source # 

Functor f => Alt (Chain ((:*:) :: (Type > Type) > (Type > Type) > Type > Type) (Proxy :: Type > Type) f) Source #  
Defined in Data.HFunctor.Chain  
Functor f => Alt (Chain (Product :: (Type > Type) > (Type > Type) > Type > Type) (Proxy :: Type > Type) f) Source #  
Defined in Data.HFunctor.Chain  
Bind (Chain (Comp :: (Type > Type) > (Type > Type) > Type > Type) Identity f) Source #  
(Eq (i a), Eq (t f (Chain t i f) a)) => Eq (Chain t i f a) Source #  
(Ord (i a), Ord (t f (Chain t i f) a)) => Ord (Chain t i f a) Source #  
Defined in Data.HFunctor.Chain compare :: Chain t i f a > Chain t i f a > Ordering # (<) :: Chain t i f a > Chain t i f a > Bool # (<=) :: Chain t i f a > Chain t i f a > Bool # (>) :: Chain t i f a > Chain t i f a > Bool # (>=) :: Chain t i f a > Chain t i f a > Bool #  
(Read (i a), Read (t f (Chain t i f) a)) => Read (Chain t i f a) Source #  
(Show (i a), Show (t f (Chain t i f) a)) => Show (Chain t i f a) Source #  
unfoldChain :: forall t f (g :: Type > Type) i. HBifunctor t => (g ~> (i :+: t f g)) > g ~> Chain t i f Source #
reroll :: forall t i f. Tensor t i => Chain t i f ~> ListBy t f Source #
A type
is supposed to represent the successive application of
ListBy
tt
s to itself. rerollNE
takes an explicit Chain
of applications of
t
to itself and rolls it back up into an
.ListBy
t
reroll
=foldChain
nilLB
consLB
Because t
cannot be inferred from the input or output, you should call
this with XTypeApplications:
reroll
@Comp
::Chain
CompIdentity
f a >Free
f a
unrolling :: Tensor t i => ListBy t f <~> Chain t i f Source #
A type
is supposed to represent the successive application of
ListBy
tt
s to itself. The type
is an actual concrete
ADT that contains successive applications of Chain
t i ft
to itself, and you can
pattern match on each layer.
unrolling
states that the two types are isormorphic. Use unroll
and reroll
to convert between the two.
appendChain :: forall t i f. Tensor t i => t (Chain t i f) (Chain t i f) ~> Chain t i f Source #
Chain
is a monoid with respect to t
: we can "combine" them in
an associative way. The identity here is anything made with the Done
constructor.
This is essentially biretract
, but only requiring
: it
comes from the fact that Tensor
t i
is the "free Chain1
t i
".
MonoidIn
t ipureT
is Done
.
Since: 0.1.1.0
Chain1
A useful construction that works like a "nonempty linked list" of t
f
applied to itself multiple times. That is, it contains t f f
, t
f (t f f)
, t f (t f (t f f))
, etc, with f
occuring one or more
times. It is meant to be the same as
.NonEmptyBy
t
A
is explicitly one of:Chain1
t f a
f a
t f f a
t f (t f f) a
t f (t f (t f f)) a
 .. etc
Note that this is exactly the description of
. And that's "the
point": for all instances of NonEmptyBy
tAssociative
,
is
isomorphic to Chain1
t
(witnessed by NonEmptyBy
tunrollingNE
). That's big picture
of NonEmptyBy
: it's supposed to be a type that consists of all possible
selfapplications of f
to t
.
Chain1
gives you a way to work with all
in a uniform way.
Unlike for NonEmptyBy
t
in general, you can always explicitly /pattern
match/ on a NonEmptyBy
t fChain1
(with its two constructors) and do what you please
with it. You can also construct Chain1
using normal constructors
and functions.
You can convert in between
and NonEmptyBy
t f
with Chain1
t funrollNE
and rerollNE
. You can fully "collapse" a
into an Chain1
t ff
with retract
, if you have
; this could be considered
a fundamental property of semigroupness.SemigroupIn
t f
See Chain
for a version that has an "empty" value.
Another way of thinking of this is that
is the "free
Chain1
t
". Given any functor SemigroupIn
tf
,
is
a semigroup in the semigroupoidal category of endofunctors enriched by
Chain1
t ft
. So,
is the "free
Chain1
Comp
Bind
",
is the "free
Chain1
Day
Apply
", etc. You "lift" from f a
to
using Chain1
t f ainject
.
Note: this instance doesn't exist directly because of restrictions in typeclasses, but is implemented as
Associative
t =>SemigroupIn
(WrapHBF
t) (Chain1
t f)
where biretract
is appendChain1
.
You can fully "collapse" a
into an Chain
t i ff
with
retract
, if you have
; this could be considered
a fundamental property of monoidness.MonoidIn
t i f
This construction is inspired by iteratees and machines.
Instances
HBifunctor t => HFunctor (Chain1 t :: (k > Type) > k > Type) Source #  
HBifunctor t => Inject (Chain1 t :: (k > Type) > k > Type) Source #  
(HBifunctor t, SemigroupIn t f) => Interpret (Chain1 t :: (Type > Type) > Type > Type) (f :: Type > Type) Source #  
(Functor f, Functor (t f (Chain1 t f))) => Functor (Chain1 t f) Source #  
(Foldable f, Foldable (t f (Chain1 t f))) => Foldable (Chain1 t f) Source #  
Defined in Data.HFunctor.Chain fold :: Monoid m => Chain1 t f m > m # foldMap :: Monoid m => (a > m) > Chain1 t f a > m # foldr :: (a > b > b) > b > Chain1 t f a > b # foldr' :: (a > b > b) > b > Chain1 t f a > b # foldl :: (b > a > b) > b > Chain1 t f a > b # foldl' :: (b > a > b) > b > Chain1 t f a > b # foldr1 :: (a > a > a) > Chain1 t f a > a # foldl1 :: (a > a > a) > Chain1 t f a > a # toList :: Chain1 t f a > [a] # null :: Chain1 t f a > Bool # length :: Chain1 t f a > Int # elem :: Eq a => a > Chain1 t f a > Bool # maximum :: Ord a => Chain1 t f a > a # minimum :: Ord a => Chain1 t f a > a #  
(Traversable f, Traversable (t f (Chain1 t f))) => Traversable (Chain1 t f) Source #  
Defined in Data.HFunctor.Chain  
(Eq1 f, Eq1 (t f (Chain1 t f))) => Eq1 (Chain1 t f) Source #  
(Ord1 f, Ord1 (t f (Chain1 t f))) => Ord1 (Chain1 t f) Source #  
Defined in Data.HFunctor.Chain  
(Functor f, Read1 (t f (Chain1 t f)), Read1 f) => Read1 (Chain1 t f) Source #  
Defined in Data.HFunctor.Chain  
(Show1 (t f (Chain1 t f)), Show1 f) => Show1 (Chain1 t f) Source #  
Functor f => Apply (Chain1 Day f) Source # 

Functor f => Apply (Chain1 (Comp :: (Type > Type) > (Type > Type) > Type > Type) f) Source #  
Defined in Data.HFunctor.Chain  
Functor f => Alt (Chain1 ((:*:) :: (Type > Type) > (Type > Type) > Type > Type) f) Source # 

Functor f => Alt (Chain1 (Product :: (Type > Type) > (Type > Type) > Type > Type) f) Source # 

Functor f => Bind (Chain1 (Comp :: (Type > Type) > (Type > Type) > Type > Type) f) Source # 

(Eq (f a), Eq (t f (Chain1 t f) a)) => Eq (Chain1 t f a) Source #  
(Ord (f a), Ord (t f (Chain1 t f) a)) => Ord (Chain1 t f a) Source #  
Defined in Data.HFunctor.Chain  
(Read (f a), Read (t f (Chain1 t f) a)) => Read (Chain1 t f a) Source #  
(Show (f a), Show (t f (Chain1 t f) a)) => Show (Chain1 t f a) Source #  
Generic (Chain1 t f a) Source #  
(Associative t, Functor f) => SemigroupIn (WrapHBF t) (Chain1 t f) Source # 

type Rep (Chain1 t f a) Source #  
Defined in Data.HFunctor.Chain type Rep (Chain1 t f a) = D1 (MetaData "Chain1" "Data.HFunctor.Chain" "functorcombinators0.2.0.0inplace" False) (C1 (MetaCons "Done1" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (f a))) :+: C1 (MetaCons "More1" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (t f (Chain1 t f) a)))) 
unfoldChain1 :: forall t f (g :: Type > Type). HBifunctor t => (g ~> (f :+: t f g)) > g ~> Chain1 t f Source #
unrollingNE :: forall t f. (Associative t, Functor f) => NonEmptyBy t f <~> Chain1 t f Source #
A type
is supposed to represent the successive application of
NonEmptyBy
tt
s to itself. The type
is an actual concrete ADT that contains
successive applications of Chain1
t ft
to itself, and you can pattern match on
each layer.
unrollingNE
states that the two types are isormorphic. Use unrollNE
and rerollNE
to convert between the two.
unrollNE :: (Associative t, Functor f) => NonEmptyBy t f ~> Chain1 t f Source #
A type
is supposed to represent the successive application of
NonEmptyBy
tt
s to itself. unrollNE
makes that successive application explicit,
buy converting it to a literal Chain1
of applications of t
to
itself.
unrollNE
=unfoldChain1
matchNE
rerollNE :: Associative t => Chain1 t f ~> NonEmptyBy t f Source #
A type
is supposed to represent the successive application of
NonEmptyBy
tt
s to itself. rerollNE
takes an explicit Chain1
of applications
of t
to itself and rolls it back up into an
.NonEmptyBy
t
rerollNE
=foldChain1
inject
consNE
appendChain1 :: forall t f. (Associative t, Functor f) => t (Chain1 t f) (Chain1 t f) ~> Chain1 t f Source #
Chain1
is a semigroup with respect to t
: we can "combine" them in
an associative way.
This is essentially biretract
, but only requiring
:
it comes from the fact that Associative
t
is the "free Chain1
t
".SemigroupIn
t
Since: 0.1.1.0
Matchable
splittingChain1 :: forall t i f. (Matchable t i, Functor f) => Chain1 t f <~> t f (Chain t i f) Source #
splitChain1 :: forall t i f. Tensor t i => Chain1 t f ~> t f (Chain t i f) Source #
The "forward" function representing splittingChain1
. Provided here
as a separate function because it does not require
.Functor
f
matchingChain :: forall t i f. (Tensor t i, Matchable t i, Functor f) => Chain t i f <~> (i :+: Chain1 t f) Source #
unmatchChain :: forall t i f. Tensor t i => (i :+: Chain1 t f) ~> Chain t i f Source #
The "reverse" function representing matchingChain
. Provided here
as a separate function because it does not require
.Functor
f