-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Various extra monoid-related definitions and utilities
--   
--   Various extra monoid-related definitions and utilities, such as monoid
--   actions, monoid coproducts, semi-direct products, "deletable" monoids,
--   "split" monoids, and "cut" monoids.
@package monoid-extras
@version 0.6.1


-- | Monoid and semigroup actions.
module Data.Monoid.Action

-- | Type class for monoid (and semigroup) actions, where monoidal values
--   of type <tt>m</tt> "act" on values of another type <tt>s</tt>.
--   Instances are required to satisfy the laws
--   
--   <ul>
--   <li><pre>act mempty = id</pre></li>
--   <li><pre>act (m1 `mappend` m2) = act m1 . act m2</pre></li>
--   </ul>
--   
--   Semigroup instances are required to satisfy the second law but with
--   (<a>&lt;&gt;</a>) instead of <a>mappend</a>. Additionally, if the type
--   <tt>s</tt> has any algebraic structure, <tt>act m</tt> should be a
--   homomorphism. For example, if <tt>s</tt> is also a monoid we should
--   have <tt>act m mempty = mempty</tt> and <tt>act m (s1 `mappend` s2) =
--   (act m s1) `mappend` (act m s2)</tt>.
--   
--   By default, <tt>act = const id</tt>, so for a type <tt>M</tt> which
--   should have no action on anything, it suffices to write
--   
--   <pre>
--   instance Action M s
--   </pre>
--   
--   with no method implementations.
--   
--   It is a bit awkward dealing with instances of <tt>Action</tt>, since
--   it is a multi-parameter type class but we can't add any functional
--   dependencies---the relationship between monoids and the types on which
--   they act is truly many-to-many. In practice, this library has chosen
--   to have instance selection for <tt>Action</tt> driven by the
--   <i>first</i> type parameter. That is, you should never write an
--   instance of the form <tt>Action m SomeType</tt> since it will overlap
--   with instances of the form <tt>Action SomeMonoid t</tt>. Newtype
--   wrappers can be used to (awkwardly) get around this.
class Action m s

-- | Convert a value of type <tt>m</tt> to an action on <tt>s</tt> values.
act :: Action m s => m -> s -> s
instance Data.Monoid.Action.Action () l
instance Data.Monoid.Action.Action m s => Data.Monoid.Action.Action (GHC.Maybe.Maybe m) s
instance Data.Monoid.Action.Action (Data.Semigroup.Internal.Endo a) a


-- | The coproduct of two monoids.
module Data.Monoid.Coproduct

-- | <tt>m :+: n</tt> is the coproduct of monoids <tt>m</tt> and
--   <tt>n</tt>. Values of type <tt>m :+: n</tt> consist of alternating
--   lists of <tt>m</tt> and <tt>n</tt> values. The empty list is the
--   identity, and composition is list concatenation, with appropriate
--   combining of adjacent elements when possible.
data m :+: n

-- | Injection from the left monoid into a coproduct.
inL :: m -> m :+: n

-- | Injection from the right monoid into a coproduct.
inR :: n -> m :+: n

-- | Prepend a value from the left monoid.
mappendL :: m -> (m :+: n) -> m :+: n

-- | Prepend a value from the right monoid.
mappendR :: n -> (m :+: n) -> m :+: n

-- | <tt>killL</tt> takes a value in a coproduct monoid and sends all the
--   values from the left monoid to the identity.
killL :: Monoid n => (m :+: n) -> n

-- | <tt>killR</tt> takes a value in a coproduct monoid and sends all the
--   values from the right monoid to the identity.
killR :: Monoid m => (m :+: n) -> m

-- | Take a value from a coproduct monoid where the left monoid has an
--   action on the right, and "untangle" it into a pair of values. In
--   particular,
--   
--   <pre>
--   m1 &lt;&gt; n1 &lt;&gt; m2 &lt;&gt; n2 &lt;&gt; m3 &lt;&gt; n3 &lt;&gt; ...
--   </pre>
--   
--   is sent to
--   
--   <pre>
--   (m1 &lt;&gt; m2 &lt;&gt; m3 &lt;&gt; ..., (act m1 n1) &lt;&gt; (act (m1 &lt;&gt; m2) n2) &lt;&gt; (act (m1 &lt;&gt; m2 &lt;&gt; m3) n3) &lt;&gt; ...)
--   </pre>
--   
--   That is, before combining <tt>n</tt> values, every <tt>n</tt> value is
--   acted on by all the <tt>m</tt> values to its left.
untangle :: (Action m n, Monoid m, Monoid n) => (m :+: n) -> (m, n)
instance (GHC.Show.Show m, GHC.Show.Show n) => GHC.Show.Show (m Data.Monoid.Coproduct.:+: n)
instance GHC.Base.Semigroup (m Data.Monoid.Coproduct.:+: n)
instance GHC.Base.Monoid (m Data.Monoid.Coproduct.:+: n)
instance (Data.Monoid.Action.Action m r, Data.Monoid.Action.Action n r) => Data.Monoid.Action.Action (m Data.Monoid.Coproduct.:+: n) r


-- | The <tt>Cut</tt> monoid transformer introduces "cut points" such that
--   all values between any two cut points are thrown away. That is,
--   
--   <pre>
--   a b c | d e | f g h i | j k  ==  a b c | j k
--   </pre>
module Data.Monoid.Cut

-- | A value of type <tt>Cut m</tt> is either a single <tt>m</tt>, or a
--   pair of <tt>m</tt>'s separated by a divider. The divider represents a
--   "cut point".
--   
--   <tt>Cut</tt> is similar to <a>Data.Monoid.Split</a>, but split keeps
--   only the rightmost divider and accumulates all values, whereas cut
--   always keeps the leftmost and rightmost divider, coalescing them into
--   one and throwing away all the information in between.
--   
--   <tt>Split</tt> uses the asymmetric constructor <tt>:|</tt>, and
--   <tt>Cut</tt> the symmetric constructor <tt>:||:</tt>, to emphasize the
--   inherent asymmetry of <tt>Split</tt> and symmetry of <tt>Cut</tt>.
--   <tt>Split</tt> keeps only the rightmost split and combines everything
--   on the left; <tt>Cut</tt> keeps the outermost splits and throws away
--   everything in between.
data Cut m
Uncut :: m -> Cut m
(:||:) :: m -> m -> Cut m
infix 5 :||:

-- | A convenient name for <tt>mempty :||: mempty</tt>, so composing with
--   <tt>cut</tt> introduces a cut point. For example, <tt>Uncut a &lt;&gt;
--   cut &lt;&gt; Uncut b == a :||: b</tt>.
cut :: Monoid m => Cut m
instance Data.Traversable.Traversable Data.Monoid.Cut.Cut
instance Data.Foldable.Foldable Data.Monoid.Cut.Cut
instance GHC.Base.Functor Data.Monoid.Cut.Cut
instance GHC.Read.Read m => GHC.Read.Read (Data.Monoid.Cut.Cut m)
instance GHC.Show.Show m => GHC.Show.Show (Data.Monoid.Cut.Cut m)
instance Data.Data.Data m => Data.Data.Data (Data.Monoid.Cut.Cut m)
instance GHC.Base.Semigroup m => GHC.Base.Semigroup (Data.Monoid.Cut.Cut m)
instance (GHC.Base.Semigroup m, GHC.Base.Monoid m) => GHC.Base.Monoid (Data.Monoid.Cut.Cut m)


-- | A monoid transformer that allows deleting information from a
--   concatenation of monoidal values.
module Data.Monoid.Deletable

-- | If <tt>m</tt> is a <a>Monoid</a>, then <tt>Deletable m</tt>
--   (intuitively speaking) adds two distinguished new elements <tt>[</tt>
--   and <tt>]</tt>, such that an occurrence of [ "deletes" everything from
--   it to the next ]. For example,
--   
--   <pre>
--   abc[def]gh == abcgh
--   </pre>
--   
--   This is all you really need to know to <i>use</i> <tt>Deletable m</tt>
--   values; to understand the actual implementation, read on.
--   
--   To properly deal with nesting and associativity we need to be able to
--   assign meanings to things like <tt>[[</tt>, <tt>][</tt>, and so on.
--   (We cannot just define, say, <tt>[[ == [</tt>, since then <tt>([[)] ==
--   [] == id</tt> but <tt>[([]) == [id == [</tt>.) Formally, elements of
--   <tt>Deletable m</tt> are triples of the form (r, m, l) representing
--   words <tt>]^r m [^l</tt>. When combining two triples (r1, m1, l1) and
--   (r2, m2, l2) there are three cases:
--   
--   <ul>
--   <li>If l1 == r2 then the [s from the left and ]s from the right
--   exactly cancel, and we are left with (r1, m1 &lt;&gt; m2, l2).</li>
--   <li>If l1 &lt; r2 then all of the [s cancel with some of the ]s, but
--   m1 is still inside the remaining ]s and is deleted, yielding (r1 + r2
--   - l1, m2, l2)</li>
--   <li>The remaining case is symmetric with the second.</li>
--   </ul>
data Deletable m
Deletable :: Int -> m -> Int -> Deletable m

-- | Project the wrapped value out of a <a>Deletable</a> value.
unDelete :: Deletable m -> m

-- | Inject a value into a <a>Deletable</a> wrapper. Satisfies the property
--   
--   <pre>
--   unDelete . toDeletable === id
--   </pre>
toDeletable :: m -> Deletable m

-- | A "left bracket", which causes everything between it and the next
--   right bracket to be deleted.
deleteL :: Monoid m => Deletable m

-- | A "right bracket", denoting the end of the section that should be
--   deleted.
deleteR :: Monoid m => Deletable m
instance Data.Traversable.Traversable Data.Monoid.Deletable.Deletable
instance Data.Foldable.Foldable Data.Monoid.Deletable.Deletable
instance GHC.Base.Functor Data.Monoid.Deletable.Deletable
instance GHC.Read.Read m => GHC.Read.Read (Data.Monoid.Deletable.Deletable m)
instance GHC.Show.Show m => GHC.Show.Show (Data.Monoid.Deletable.Deletable m)
instance Data.Data.Data m => Data.Data.Data (Data.Monoid.Deletable.Deletable m)
instance GHC.Base.Semigroup m => GHC.Base.Semigroup (Data.Monoid.Deletable.Deletable m)
instance (GHC.Base.Semigroup m, GHC.Base.Monoid m) => GHC.Base.Monoid (Data.Monoid.Deletable.Deletable m)


-- | The monoid of endomorphisms over any <a>Category</a>.
module Data.Monoid.Endomorphism

-- | An <a>Endomorphism</a> in a given <a>Category</a> is a morphism from
--   some object to itself. The set of endomorphisms for a particular
--   object form a monoid, with composition as the combining operation and
--   the identity morphism as the identity element.
newtype Endomorphism k a
Endomorphism :: k a a -> Endomorphism k a
[getEndomorphism] :: Endomorphism k a -> k a a
instance GHC.Show.Show (k a a) => GHC.Show.Show (Data.Monoid.Endomorphism.Endomorphism k a)
instance Data.Semigroupoid.Semigroupoid k => GHC.Base.Semigroup (Data.Monoid.Endomorphism.Endomorphism k a)
instance (Data.Semigroupoid.Semigroupoid k, Control.Category.Category k) => GHC.Base.Monoid (Data.Monoid.Endomorphism.Endomorphism k a)
instance (Control.Category.Category k, Data.Groupoid.Groupoid k) => Data.Group.Group (Data.Monoid.Endomorphism.Endomorphism k a)


-- | Make semigroups under <a>min</a> or <a>max</a> into monoids by
--   adjoining an element corresponding to infinity (positive or negative,
--   respectively). These types are similar to <tt>Maybe (Min a)</tt> and
--   <tt>Maybe (Max a)</tt> respectively, except that the <a>Ord</a>
--   instance matches the <a>Monoid</a> instance.
module Data.Monoid.Inf

-- | <tt>Inf p a</tt> represents the type <tt>a</tt> extended with a new
--   "infinite" value, which is treated as either positive or negative
--   infinity depending on the type index <tt>p</tt>. This type exists
--   mostly for its <a>Ord</a>, <a>Semigroup</a>, and <a>Monoid</a>
--   instances.
data Inf p a
Infinity :: Inf p a
Finite :: a -> Inf p a

-- | Type index indicating positive infinity.
data Pos

-- | Type index indicating negative infinity.
data Neg

-- | The type <tt>a</tt> extended with positive infinity.
type PosInf a = Inf Pos a

-- | The type <tt>a</tt> extended with negative infinity.
type NegInf a = Inf Neg a

-- | Find the minimum of a list of values. Returns positive infinity iff
--   the list is empty.
minimum :: Ord a => [a] -> PosInf a

-- | Find the maximum of a list of values. Returns negative infinity iff
--   the list is empty.
maximum :: Ord a => [a] -> NegInf a

-- | Positive infinity.
posInfty :: PosInf a

-- | Negative infinity.
negInfty :: NegInf a

-- | Embed a finite value into the space of such values extended with
--   positive infinity.
posFinite :: a -> PosInf a

-- | Embed a finite value into the space of such values extended with
--   negative infinity.
negFinite :: a -> NegInf a
instance Data.Traversable.Traversable (Data.Monoid.Inf.Inf p)
instance Data.Foldable.Foldable (Data.Monoid.Inf.Inf p)
instance GHC.Base.Functor (Data.Monoid.Inf.Inf p)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Monoid.Inf.Inf p a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Monoid.Inf.Inf p a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Monoid.Inf.Inf p a)
instance (Data.Data.Data p, Data.Data.Data a) => Data.Data.Data (Data.Monoid.Inf.Inf p a)
instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Data.Monoid.Inf.NegInf a)
instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Data.Monoid.Inf.PosInf a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Monoid.Inf.Inf Data.Monoid.Inf.Pos a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Monoid.Inf.Inf Data.Monoid.Inf.Neg a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Data.Monoid.Inf.Inf Data.Monoid.Inf.Pos a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Data.Monoid.Inf.Inf Data.Monoid.Inf.Neg a)
instance GHC.Classes.Ord a => GHC.Base.Monoid (Data.Monoid.Inf.Inf Data.Monoid.Inf.Pos a)
instance GHC.Classes.Ord a => GHC.Base.Monoid (Data.Monoid.Inf.Inf Data.Monoid.Inf.Neg a)
instance GHC.Base.Applicative (Data.Monoid.Inf.Inf p)
instance GHC.Base.Monad (Data.Monoid.Inf.Inf p)


-- | Heterogeneous lists of monoids.
module Data.Monoid.MList
type a ::: l = (Maybe a, l)
infixr 5 :::
(*:) :: a -> l -> a ::: l
infixr 5 *:

-- | Type class for heterogeneous monoidal lists, with a single method
--   allowing construction of an empty list.
class MList l

-- | The <i>empty</i> heterogeneous list of type <tt>l</tt>. Of course,
--   <tt>empty == <a>mempty</a></tt>, but unlike <a>mempty</a>,
--   <tt>empty</tt> does not require <a>Monoid</a> constraints on all the
--   elements of <tt>l</tt>.
empty :: MList l => l

-- | The relation <tt>l :&gt;: a</tt> holds when <tt>a</tt> is the type of
--   an element in <tt>l</tt>. For example, <tt>(Char ::: Int ::: Bool :::
--   Nil) :&gt;: Int</tt>.
class l :>: a

-- | Inject a value into an otherwise empty heterogeneous list.
inj :: (:>:) l a => a -> l

-- | Get the value of type <tt>a</tt> from a heterogeneous list, if there
--   is one.
get :: (:>:) l a => l -> Maybe a

-- | Alter the value of type <tt>a</tt> by applying the given function to
--   it.
alt :: (:>:) l a => (Maybe a -> Maybe a) -> l -> l

-- | <tt>SM</tt>, an abbreviation for "single monoid" (as opposed to a
--   heterogeneous list of monoids), is only used internally to help guide
--   instance selection when defining the action of heterogeneous monoidal
--   lists on each other.
newtype SM m
SM :: m -> SM m
instance GHC.Show.Show m => GHC.Show.Show (Data.Monoid.MList.SM m)
instance (Data.Monoid.Action.Action (Data.Monoid.MList.SM a) l2, Data.Monoid.Action.Action l1 l2) => Data.Monoid.Action.Action (a, l1) l2
instance Data.Monoid.Action.Action (Data.Monoid.MList.SM a) ()
instance (Data.Monoid.Action.Action a a', Data.Monoid.Action.Action (Data.Monoid.MList.SM a) l) => Data.Monoid.Action.Action (Data.Monoid.MList.SM a) (GHC.Maybe.Maybe a', l)
instance Data.Monoid.MList.MList t => (a Data.Monoid.MList.::: t) Data.Monoid.MList.:>: a
instance (t Data.Monoid.MList.:>: a) => (b Data.Monoid.MList.::: t) Data.Monoid.MList.:>: a
instance Data.Monoid.MList.MList ()
instance Data.Monoid.MList.MList l => Data.Monoid.MList.MList (a Data.Monoid.MList.::: l)


-- | A type for representing values with an additional bit saying whether
--   the value is "just a recommendation" (to be used only if nothing
--   better comes along) or a "commitment" (to certainly be used,
--   overriding merely recommended values), along with corresponding
--   <tt>Semigroup</tt> and <tt>Monoid</tt> instances.
module Data.Monoid.Recommend

-- | A value of type <tt>Recommend a</tt> consists of a value of type
--   <tt>a</tt> wrapped up in one of two constructors. The
--   <tt>Recommend</tt> constructor indicates a "non-committal
--   recommendation"---that is, the given value should be used if no
--   other/better values are available. The <tt>Commit</tt> constructor
--   indicates a "commitment"---a value which should definitely be used,
--   overriding any <tt>Recommend</tt>ed values.
data Recommend a
Recommend :: a -> Recommend a
Commit :: a -> Recommend a

-- | Extract the value of type <tt>a</tt> wrapped in <tt>Recommend a</tt>.
getRecommend :: Recommend a -> a
instance Data.Traversable.Traversable Data.Monoid.Recommend.Recommend
instance Data.Foldable.Foldable Data.Monoid.Recommend.Recommend
instance Data.Data.Data a => Data.Data.Data (Data.Monoid.Recommend.Recommend a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Monoid.Recommend.Recommend a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Monoid.Recommend.Recommend a)
instance GHC.Base.Functor Data.Monoid.Recommend.Recommend
instance GHC.Read.Read a => GHC.Read.Read (Data.Monoid.Recommend.Recommend a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Monoid.Recommend.Recommend a)
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Monoid.Recommend.Recommend a)
instance (GHC.Base.Semigroup a, GHC.Base.Monoid a) => GHC.Base.Monoid (Data.Monoid.Recommend.Recommend a)

module Data.Monoid.SemiDirectProduct

-- | The semi-direct product of monoids <tt>s</tt> and <tt>m</tt>, which is
--   a monoid when <tt>m</tt> acts on <tt>s</tt>. Structurally, the
--   semi-direct product is just a pair <tt>(s,m)</tt>. However, the monoid
--   instance is different. In particular, we have
--   
--   <pre>
--   (s1,m1) &lt;&gt; (s2,m2) = (s1 &lt;&gt; (m1 `act` s2), m1 &lt;&gt; m2)
--   </pre>
--   
--   We think of the <tt>m</tt> values as a "tag" decorating the <tt>s</tt>
--   values, which also affect the way the <tt>s</tt> values combine.
--   
--   We call the monoid <tt>m</tt> the quotient monoid and the monoid
--   <tt>s</tt> the sub-monoid of the semi-direct product. The semi-direct
--   product <tt>Semi s m</tt> is an extension of the monoid <tt>s</tt>
--   with <tt>m</tt> being the quotient.
data Semi s m
unSemi :: Semi s m -> (s, m)

-- | Tag an <tt>s</tt> value with an <tt>m</tt> value to create an element
--   of the semi-direct product.
tag :: s -> m -> Semi s m

-- | The injection map, <i>i.e.</i> give an <tt>s</tt> value a trivial tag.
inject :: Monoid m => s -> Semi s m

-- | Forget the monoidal tag. Of course, <tt>untag . inject = id</tt>, and
--   <tt>untag (tag s m) = s</tt>.
untag :: Semi s m -> s

-- | Embed a "tag" value as a value of type <tt>Semi s m</tt>. Note that
--   
--   <pre>
--   inject s &lt;&gt; embed m = tag s m
--   </pre>
--   
--   and
--   
--   <tt>embed m &lt;&gt; inject s</tt> = tag (act m s) m@
--   
--   The semi-direct product gives a split extension of <tt>s</tt> by
--   <tt>m</tt>. This allows us to embed <tt>m</tt> into the semi-direct
--   product. This is the embedding map. The quotient and embed maps should
--   satisfy the equation <tt>quotient . embed = id</tt>.
embed :: Monoid s => m -> Semi s m

-- | The quotient map, <i>i.e.</i> retrieve the monoidal tag value.
quotient :: Semi s m -> m
instance (GHC.Base.Semigroup m, GHC.Base.Semigroup s, Data.Monoid.Action.Action m s) => GHC.Base.Semigroup (Data.Monoid.SemiDirectProduct.Semi s m)
instance (GHC.Base.Monoid m, GHC.Base.Monoid s, Data.Monoid.Action.Action m s) => GHC.Base.Monoid (Data.Monoid.SemiDirectProduct.Semi s m)


-- | A strict version of the semi-direct product. If a monoid m acts on s
--   then this version of the semi-direct product is strict in the
--   m-portion of the semi-direct product.
module Data.Monoid.SemiDirectProduct.Strict

-- | The semi-direct product of monoids <tt>s</tt> and <tt>m</tt>, which is
--   a monoid when <tt>m</tt> acts on <tt>s</tt>. Structurally, the
--   semi-direct product is just a pair <tt>(s,m)</tt>. However, the monoid
--   instance is different. In particular, we have
--   
--   <pre>
--   (s1,m1) &lt;&gt; (s2,m2) = (s1 &lt;&gt; (m1 `act` s2), m1 &lt;&gt; m2)
--   </pre>
--   
--   We call the monoid <tt>m</tt> the quotient monoid and the monoid
--   <tt>s</tt> the sub-monoid of the semi-direct product. The semi-direct
--   product <tt>Semi s m</tt> is an extension of the monoid <tt>s</tt>
--   with <tt>m</tt> being the quotient.
data Semi s m
unSemi :: Semi s m -> (s, m)

-- | Tag an <tt>s</tt> value with an <tt>m</tt> value to create an element
--   of the semi-direct product.
tag :: s -> m -> Semi s m

-- | The injection map, <i>i.e.</i> give an <tt>s</tt> value a trivial tag.
inject :: Monoid m => s -> Semi s m

-- | Forget the monoidal tag. Of course, <tt>untag . inject = id</tt>, and
--   <tt>untag (tag s m) = s</tt>.
untag :: Semi s m -> s

-- | Embed a "tag" value as a value of type <tt>Semi s m</tt>. Note that
--   
--   <pre>
--   inject s &lt;&gt; embed m = tag s m
--   </pre>
--   
--   and
--   
--   <tt>embed m &lt;&gt; inject s</tt> = tag (act m s) m@
--   
--   The semi-direct product gives a split extension of <tt>s</tt> by
--   <tt>m</tt>. This allows us to embed <tt>m</tt> into the semi-direct
--   product. This is the embedding map. The quotient and embed maps should
--   satisfy the equation <tt>quotient . embed = id</tt>.
embed :: Monoid s => m -> Semi s m

-- | The quotient map, <i>i.e.</i> retrieve the monoidal tag value.
quotient :: Semi s m -> m
instance (GHC.Base.Semigroup m, GHC.Base.Semigroup s, Data.Monoid.Action.Action m s) => GHC.Base.Semigroup (Data.Monoid.SemiDirectProduct.Strict.Semi s m)
instance (GHC.Base.Monoid m, GHC.Base.Monoid s, Data.Monoid.Action.Action m s) => GHC.Base.Monoid (Data.Monoid.SemiDirectProduct.Strict.Semi s m)


-- | Sometimes we want to accumulate values from some monoid, but have the
--   ability to introduce a "split" which separates values on either side.
--   Only the rightmost split is kept. For example,
--   
--   <pre>
--   a b c | d e | f g h == a b c d e | f g h
--   </pre>
--   
--   In the diagrams graphics framework this is used when accumulating
--   transformations to be applied to primitive diagrams: the
--   <tt>freeze</tt> operation introduces a split, since only
--   transformations occurring outside the freeze should be applied to
--   attributes.
module Data.Monoid.Split

-- | A value of type <tt>Split m</tt> is either a single <tt>m</tt>, or a
--   pair of <tt>m</tt>'s separated by a divider. Single <tt>m</tt>'s
--   combine as usual; single <tt>m</tt>'s combine with split values by
--   combining with the value on the appropriate side; when two split
--   values meet only the rightmost split is kept, with both the values
--   from the left split combining with the left-hand value of the right
--   split.
--   
--   <a>Data.Monoid.Cut</a> is similar, but uses a different scheme for
--   composition. <tt>Split</tt> uses the asymmetric constructor
--   <tt>:|</tt>, and <tt>Cut</tt> the symmetric constructor <tt>:||:</tt>,
--   to emphasize the inherent asymmetry of <tt>Split</tt> and symmetry of
--   <tt>Cut</tt>. <tt>Split</tt> keeps only the rightmost split and
--   combines everything on the left; <tt>Cut</tt> keeps the outermost
--   splits and throws away everything in between.
data Split m
M :: m -> Split m
(:|) :: m -> m -> Split m
infix 5 :|

-- | A convenient name for <tt>mempty :| mempty</tt>, so <tt>M a &lt;&gt;
--   split &lt;&gt; M b == a :| b</tt>.
split :: Monoid m => Split m

-- | "Unsplit" a split monoid value, combining the two values into one (or
--   returning the single value if there is no split).
unsplit :: Semigroup m => Split m -> m
instance Data.Traversable.Traversable Data.Monoid.Split.Split
instance Data.Foldable.Foldable Data.Monoid.Split.Split
instance GHC.Base.Functor Data.Monoid.Split.Split
instance GHC.Classes.Eq m => GHC.Classes.Eq (Data.Monoid.Split.Split m)
instance GHC.Read.Read m => GHC.Read.Read (Data.Monoid.Split.Split m)
instance GHC.Show.Show m => GHC.Show.Show (Data.Monoid.Split.Split m)
instance Data.Data.Data m => Data.Data.Data (Data.Monoid.Split.Split m)
instance GHC.Base.Semigroup m => GHC.Base.Semigroup (Data.Monoid.Split.Split m)
instance (GHC.Base.Semigroup m, GHC.Base.Monoid m) => GHC.Base.Monoid (Data.Monoid.Split.Split m)
instance Data.Monoid.Action.Action m n => Data.Monoid.Action.Action (Data.Monoid.Split.Split m) n


-- | Convenience alias for the combination of <tt>Monoid</tt> and
--   <tt>Semigroup</tt> constraints.
module Data.Monoid.WithSemigroup

-- | For base &lt; 4.11, the <tt>Monoid'</tt> constraint is a synonym for
--   things which are instances of both <a>Semigroup</a> and <a>Monoid</a>.
--   For base version 4.11 and onwards, <tt>Monoid</tt> has
--   <tt>Semigroup</tt> as a superclass already, so for backwards
--   compatibility <tt>Monoid'</tt> is provided as a synonym for
--   <tt>Monoid</tt>.
type Monoid' = Monoid


-- | A strict coproduct of two monoids.
module Data.Monoid.Coproduct.Strict

-- | <tt>m :+: n</tt> is the coproduct of monoids <tt>m</tt> and
--   <tt>n</tt>. Concatentation is equivilent to
--   
--   <pre>
--   (m1 :+: n1) &lt;&gt; (m2 :+: n2) = (m1 &lt;&gt; m2) :+: (n1 &lt;&gt; act m1 n2)@
--   </pre>
--   
--   but has a more efficient internal implimentation.
data m :+: n

-- | Construct a coproduct with a left value.
inL :: m -> m :+: n

-- | Construct a coproduct with a right value.
inR :: n -> m :+: n

-- | Prepend a value from the left.
prependL :: Semigroup m => m -> (m :+: n) -> m :+: n

-- | Prepend a value from the right.
prependR :: Semigroup n => n -> (m :+: n) -> m :+: n

-- | Extract <tt>n</tt> from a coproduct.
killL :: (Action m n, Monoid' n) => (m :+: n) -> n

-- | Extract <tt>m</tt> from a coproduct.
killR :: Monoid m => (m :+: n) -> m
untangle :: (Action m n, Monoid m, Monoid' n) => (m :+: n) -> (m, n)

-- | Lens onto the both <tt>m</tt> and <tt>n</tt>.
untangled :: (Action m n, Monoid m, Monoid' n) => Lens (m :+: n) (m' :+: n') (m, n) (m', n')

-- | Lens onto the left value of a coproduct.
_L :: (Action m n, Monoid m, Semigroup n) => Lens (m :+: n) (m' :+: n) m m'

-- | Lens onto the right value of a coproduct.
_R :: (Action m n, Monoid' n) => Lens (m :+: n) (m :+: n') n n'
instance (Data.Monoid.Action.Action m n, GHC.Base.Monoid m, Data.Monoid.WithSemigroup.Monoid' n, GHC.Show.Show m, GHC.Show.Show n) => GHC.Show.Show (m Data.Monoid.Coproduct.Strict.:+: n)
instance (Data.Monoid.Action.Action m n, GHC.Base.Semigroup m, GHC.Base.Semigroup n) => GHC.Base.Semigroup (m Data.Monoid.Coproduct.Strict.:+: n)
instance (Data.Monoid.Action.Action m n, GHC.Base.Semigroup m, GHC.Base.Semigroup n) => GHC.Base.Monoid (m Data.Monoid.Coproduct.Strict.:+: n)
instance (Data.Monoid.Action.Action m n, Data.Monoid.Action.Action m r, Data.Monoid.Action.Action n r, GHC.Base.Semigroup n) => Data.Monoid.Action.Action (m Data.Monoid.Coproduct.Strict.:+: n) r
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Monoid.Coproduct.Strict.Possible a)
instance GHC.Base.Semigroup a => GHC.Base.Monoid (Data.Monoid.Coproduct.Strict.Possible a)
