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


-- | A partial binary associative operator
--   
--   A partial semigroup is like a semigroup, but the operator is partial.
--   We represent this in Haskell as a total function <tt>(&lt;&gt;?) :: a
--   -&gt; a -&gt; Maybe a</tt>.
@package partial-semigroup
@version 0.3.0.3


-- | A <i>semigroup</i> (<a>Semigroup</a>) is a set with a binary
--   associative operation (<tt>&lt;&gt;</tt>). This module defines a
--   <i>partial semigroup</i> (<a>PartialSemigroup</a>), a semigroup for
--   which <tt>&lt;&gt;</tt> is not required to be defined over all inputs.
module Data.PartialSemigroup

-- | A <a>PartialSemigroup</a> is like a <a>Semigroup</a>, but with an
--   operator returning <tt><a>Maybe</a> a</tt> rather than <tt>a</tt>.
--   
--   For comparison:
--   
--   <pre>
--   (<a>&lt;&gt;</a>)  :: <a>Semigroup</a> a        =&gt; a -&gt; a -&gt; a
--   (<a>&lt;&gt;?</a>) :: <a>PartialSemigroup</a> a =&gt; a -&gt; a -&gt; <a>Maybe</a> a
--   </pre>
--   
--   <h3>The associativity axiom for partial semigroups</h3>
--   
--   For all <tt>x</tt>, <tt>y</tt>, <tt>z</tt>:
--   
--   <ul>
--   <li>If <tt>x <a>&lt;&gt;?</a> y = <a>Just</a> xy</tt> and <tt>y
--   <a>&lt;&gt;?</a> z = <a>Just</a> yz</tt>, then<ul><li><tt>x
--   <a>&lt;&gt;?</a> yz = xy <a>&lt;&gt;?</a> z</tt>.</li></ul></li>
--   </ul>
--   
--   <h4>Relationship to the semigroup associativity axiom</h4>
--   
--   The partial semigroup associativity axiom is a natural adaptation of
--   the semigroup associativity axiom
--   
--   <pre>
--   x <a>&lt;&gt;</a> (y <a>&lt;&gt;</a> z) = (x <a>&lt;&gt;</a> y) <a>&lt;&gt;</a> z
--   </pre>
--   
--   with a slight modification to accommodate situations where
--   <a>&lt;&gt;</a> is undefined. We may gain some insight into the
--   connection between <a>Semigroup</a> and <a>PartialSemigroup</a> by
--   rephrasing the partial semigroup associativity in terms of a partial
--   <a>&lt;&gt;</a> operator thusly:
--   
--   For all <tt>x</tt>, <tt>y</tt>, <tt>z</tt>:
--   
--   <ul>
--   <li>If <tt>x <a>&lt;&gt;</a> y</tt> and <tt>y <a>&lt;&gt;</a> z</tt>
--   are both defined, then<ul><li><tt>x <a>&lt;&gt;</a> (y <a>&lt;&gt;</a>
--   z)</tt> is defined if and only if <tt>(x <a>&lt;&gt;</a> y)
--   <a>&lt;&gt;</a> z</tt> is defined, and</li><li>if these things
--   <i>are</i> all defined, then the axiom for total semigroups <tt>x
--   <a>&lt;&gt;</a> (y <a>&lt;&gt;</a> z) = (x <a>&lt;&gt;</a> y)
--   <a>&lt;&gt;</a> z</tt> must hold.</li></ul></li>
--   </ul>
class PartialSemigroup a
(<>?) :: PartialSemigroup a => a -> a -> Maybe a

-- | A wrapper for <a>Either</a> where the <a>PartialSemigroup</a> operator
--   is defined only over <a>Left</a> values.
--   
--   <h4>Examples</h4>
--   
--   Two <a>Left</a>s make a <a>Just</a>.
--   
--   <pre>
--   &gt;&gt;&gt; AppendLeft (Left "ab") &lt;&gt;? AppendLeft (Left "cd")
--   Just (AppendLeft {unAppendLeft = Left "abcd"})
--   </pre>
--   
--   Anything else produces <a>Nothing</a>
--   
--   <pre>
--   &gt;&gt;&gt; AppendLeft (Right "ab") &lt;&gt;? AppendLeft (Right "cd")
--   Nothing
--   </pre>
--   
--   <a>groupAndConcat</a> combines consecutive <a>Left</a> values, leaving
--   the <a>Right</a> values unmodified.
--   
--   <pre>
--   &gt;&gt;&gt; xs = [Left "a", Left "b", Right "c", Right "d", Left "e", Left "f"]
--   
--   &gt;&gt;&gt; fmap unAppendLeft . groupAndConcat . fmap AppendLeft $ xs
--   [Left "ab",Right "c",Right "d",Left "ef"]
--   </pre>
newtype AppendLeft a b
AppendLeft :: Either a b -> AppendLeft a b
[unAppendLeft] :: AppendLeft a b -> Either a b

-- | A wrapper for <a>Either</a> where the <a>PartialSemigroup</a> operator
--   is defined only over <a>Right</a> values.
--   
--   <h4>Examples</h4>
--   
--   Two <a>Right</a>s make a <a>Just</a>.
--   
--   <pre>
--   &gt;&gt;&gt; AppendRight (Right "ab") &lt;&gt;? AppendRight (Right "cd")
--   Just (AppendRight {unAppendRight = Right "abcd"})
--   </pre>
--   
--   Anything else produces <a>Nothing</a>
--   
--   <pre>
--   &gt;&gt;&gt; AppendRight (Left "ab") &lt;&gt;? AppendRight (Left "cd")
--   Nothing
--   </pre>
--   
--   <a>groupAndConcat</a> combines consecutive <a>Right</a> values,
--   leaving the <a>Left</a> values unmodified.
--   
--   <pre>
--   &gt;&gt;&gt; xs = [Left "a", Left "b", Right "c", Right "d", Left "e", Left "f"]
--   
--   &gt;&gt;&gt; fmap unAppendRight . groupAndConcat . fmap AppendRight $ xs
--   [Left "a",Left "b",Right "cd",Left "e",Left "f"]
--   </pre>
newtype AppendRight a b
AppendRight :: Either a b -> AppendRight a b
[unAppendRight] :: AppendRight a b -> Either a b

-- | Apply a semigroup operation to any pairs of consecutive list elements
--   where the semigroup operation is defined over them.
--   
--   <h4>Examples</h4>
--   
--   For <a>Either</a>, <a>groupAndConcat</a> combines contiguous sublists
--   of <a>Left</a> and contiguous sublists of <a>Right</a>.
--   
--   <pre>
--   &gt;&gt;&gt; xs = [Left "a", Right "b", Right "c", Left "d", Left "e", Left "f"]
--   
--   &gt;&gt;&gt; groupAndConcat xs
--   [Left "a",Right "bc",Left "def"]
--   </pre>
groupAndConcat :: PartialSemigroup a => [a] -> [a]

-- | If <tt>xs</tt> is nonempty and the partial semigroup operator is
--   defined for all pairs of values in <tt>xs</tt>, then
--   <tt><a>partialConcat</a> xs</tt> produces a <a>Just</a> result with
--   the combination of all the values. Otherwise, returns <a>Nothing</a>.
--   
--   <h4>Examples</h4>
--   
--   When all values can combine, we get a <a>Just</a> of their
--   combination.
--   
--   <pre>
--   &gt;&gt;&gt; partialConcat [Left "a", Left "b", Left "c"]
--   Just (Left "abc")
--   </pre>
--   
--   When some values cannot be combined, we get <a>Nothing</a>.
--   
--   <pre>
--   &gt;&gt;&gt; partialConcat [Left "a", Left "b", Right "c"]
--   Nothing
--   </pre>
--   
--   When the list is empty, we get <a>Nothing</a>.
--   
--   <pre>
--   &gt;&gt;&gt; partialConcat []
--   Nothing
--   </pre>
partialConcat :: PartialSemigroup a => [a] -> Maybe a

-- | Like <a>partialConcat</a>, but for non-empty lists.
--   
--   <h4>Examples</h4>
--   
--   When all values can combine, we get a <a>Just</a> of their
--   combination.
--   
--   <pre>
--   &gt;&gt;&gt; partialConcat1 (Left "a" :| [Left "b", Left "c"])
--   Just (Left "abc")
--   </pre>
--   
--   When some values cannot be combined, we get <a>Nothing</a>.
--   
--   <pre>
--   &gt;&gt;&gt; partialConcat1 (Left "a" :| [Left "b", Right "c"])
--   Nothing
--   </pre>
partialConcat1 :: PartialSemigroup a => NonEmpty a -> Maybe a

-- | <h4>Examples</h4>
--   
--   If lists are the same length and each pair of elements successfully,
--   then we get a <a>Just</a> result.
--   
--   <pre>
--   &gt;&gt;&gt; xs = [Left "a", Left "b", Right "c"]
--   
--   &gt;&gt;&gt; ys = [Left "1", Left "2", Right "3"]
--   
--   &gt;&gt;&gt; partialZip xs ys
--   Just [Left "a1",Left "b2",Right "c3"]
--   </pre>
--   
--   If the pairs do not all combine, then we get <a>Nothing</a>.
--   
--   <pre>
--   &gt;&gt;&gt; xs = [Left "a", Left "b", Right "c"]
--   
--   &gt;&gt;&gt; ys = [Left "1", Right "2", Right "3"]
--   
--   &gt;&gt;&gt; partialZip xs ys
--   Nothing
--   </pre>
--   
--   If the lists have different lengths, then we get <a>Nothing</a>.
--   
--   <pre>
--   &gt;&gt;&gt; xs = [Left "a", Left "b", Right "c"]
--   
--   &gt;&gt;&gt; ys = [Left "1", Left "2"]
--   
--   &gt;&gt;&gt; partialZip xs ys
--   Nothing
--   </pre>
partialZip :: PartialSemigroup a => [a] -> [a] -> Maybe [a]

-- | Like <a>partialZip</a>, but for non-empty lists.
--   
--   <h4>Examples</h4>
--   
--   If lists are the same length and each pair of elements successfully,
--   then we get a <a>Just</a> result.
--   
--   <pre>
--   &gt;&gt;&gt; xs = Left "a" :| [Left "b", Right "c"]
--   
--   &gt;&gt;&gt; ys = Left "1" :| [Left "2", Right "3"]
--   
--   &gt;&gt;&gt; partialZip1 xs ys
--   Just (Left "a1" :| [Left "b2",Right "c3"])
--   </pre>
--   
--   If the pairs do not all combine, then we get <a>Nothing</a>.
--   
--   <pre>
--   &gt;&gt;&gt; xs = Left "a" :| [Left "b", Right "c"]
--   
--   &gt;&gt;&gt; ys = Left "1" :| [Right "2", Right "3"]
--   
--   &gt;&gt;&gt; partialZip1 xs ys
--   Nothing
--   </pre>
--   
--   If the lists have different lengths, then we get <a>Nothing</a>.
--   
--   <pre>
--   &gt;&gt;&gt; xs = Left "a" :| [Left "b", Right "c"]
--   
--   &gt;&gt;&gt; ys = Left "1" :| [Left "2"]
--   
--   &gt;&gt;&gt; partialZip1 xs ys
--   Nothing
--   </pre>
partialZip1 :: PartialSemigroup a => NonEmpty a -> NonEmpty a -> Maybe (NonEmpty a)

-- | A wrapper to turn any value with a <a>Semigroup</a> instance into a
--   value with a <a>PartialSemigroup</a> instance whose <a>&lt;&gt;?</a>
--   operator always returns <a>Just</a>.
--   
--   <h4>Examples</h4>
--   
--   <pre>
--   &gt;&gt;&gt; Total "ab" &lt;&gt;? Total "cd"
--   Just (Total {unTotal = "abcd"})
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; f = getProduct . unTotal
--   
--   &gt;&gt;&gt; g = Total . Product
--   
--   &gt;&gt;&gt; fmap f . partialConcat . fmap g $ [1..4]
--   Just 24
--   </pre>
newtype Total a
Total :: a -> Total a
[unTotal] :: Total a -> a

-- | A wrapper for <a>Maybe</a> with an error-propagating <a>Semigroup</a>.
newtype Partial a
Partial :: Maybe a -> Partial a
[unPartial] :: Partial a -> Maybe a
instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.PartialSemigroup.AppendRight a b)
instance (GHC.Read.Read a, GHC.Read.Read b) => GHC.Read.Read (Data.PartialSemigroup.AppendRight a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.PartialSemigroup.AppendRight a b)
instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.PartialSemigroup.AppendRight a b)
instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.PartialSemigroup.AppendLeft a b)
instance (GHC.Read.Read a, GHC.Read.Read b) => GHC.Read.Read (Data.PartialSemigroup.AppendLeft a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.PartialSemigroup.AppendLeft a b)
instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.PartialSemigroup.AppendLeft a b)
instance GHC.Show.Show a => GHC.Show.Show (Data.PartialSemigroup.Total a)
instance GHC.Read.Read a => GHC.Read.Read (Data.PartialSemigroup.Total a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.PartialSemigroup.Total a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.PartialSemigroup.Total a)
instance GHC.Show.Show a => GHC.Show.Show (Data.PartialSemigroup.Partial a)
instance GHC.Read.Read a => GHC.Read.Read (Data.PartialSemigroup.Partial a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.PartialSemigroup.Partial a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.PartialSemigroup.Partial a)
instance Data.PartialSemigroup.PartialSemigroup b => Data.PartialSemigroup.PartialSemigroup (Data.PartialSemigroup.AppendRight a b)
instance Data.PartialSemigroup.PartialSemigroup a => Data.PartialSemigroup.PartialSemigroup (Data.PartialSemigroup.AppendLeft a b)
instance Data.Semigroup.Semigroup a => Data.PartialSemigroup.PartialSemigroup (Data.PartialSemigroup.Total a)
instance Data.PartialSemigroup.PartialSemigroup a => Data.Semigroup.Semigroup (Data.PartialSemigroup.Partial a)
instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.PartialSemigroup.Partial a)
instance Data.PartialSemigroup.PartialSemigroup ()
instance Data.PartialSemigroup.PartialSemigroup [a]
instance GHC.Num.Num a => Data.PartialSemigroup.PartialSemigroup (Data.Monoid.Sum a)
instance GHC.Num.Num a => Data.PartialSemigroup.PartialSemigroup (Data.Monoid.Product a)
instance Data.PartialSemigroup.PartialSemigroup a => Data.PartialSemigroup.PartialSemigroup (Data.Functor.Identity.Identity a)
instance (Data.PartialSemigroup.PartialSemigroup a, Data.PartialSemigroup.PartialSemigroup b) => Data.PartialSemigroup.PartialSemigroup (Data.Either.Either a b)
instance (Data.PartialSemigroup.PartialSemigroup a, Data.PartialSemigroup.PartialSemigroup b) => Data.PartialSemigroup.PartialSemigroup (a, b)
instance (Data.PartialSemigroup.PartialSemigroup a, Data.PartialSemigroup.PartialSemigroup b, Data.PartialSemigroup.PartialSemigroup c) => Data.PartialSemigroup.PartialSemigroup (a, b, c)
instance Data.PartialSemigroup.PartialSemigroup a => Data.PartialSemigroup.PartialSemigroup (Control.Applicative.ZipList a)


-- | If a type derives <a>Generic</a> and all of its fields have
--   <a>PartialSemigroup</a> instances, you can get a
--   <a>PartialSemigroup</a> for free using
--   <a>genericPartialSemigroupOp</a>.
--   
--   <h2>Example</h2>
--   
--   For this demonstration we'll define a contrived example type
--   <tt>T</tt> with two constructors, <tt>A</tt> and <tt>B</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; data T = A String (Either String String) | B String deriving (Generic, Show)
--   </pre>
--   
--   And then define its <a>PartialSemigroup</a> instance using
--   <a>genericPartialSemigroupOp</a>.
--   
--   <pre>
--   &gt;&gt;&gt; instance PartialSemigroup T where (&lt;&gt;?) = genericPartialSemigroupOp
--   </pre>
--   
--   This gives us an implementation of <a>&lt;&gt;?</a> which combines
--   values only if they have the same structure.
--   
--   <pre>
--   &gt;&gt;&gt; A "s" (Left "x") &lt;&gt;? A "t" (Left "y")
--   Just (A "st" (Left "xy"))
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; B "x" &lt;&gt;? B "y"
--   Just (B "xy")
--   </pre>
--   
--   For values that do <i>not</i> have the same structure,
--   <a>&lt;&gt;?</a> produces <a>Nothing</a>.
--   
--   <pre>
--   &gt;&gt;&gt; A "s" (Left "x") &lt;&gt;? A "t" (Right "y")
--   Nothing
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; A "x" (Left "y") &lt;&gt;? B "z"
--   Nothing
--   </pre>
module Data.PartialSemigroup.Generics
genericPartialSemigroupOp :: (Generic a, PartialSemigroupRep (Rep a)) => a -> a -> Maybe a

-- | The class of generic type <a>Rep</a>s for which we can automatically
--   derive <a>PartialSemigroup</a>:
--   
--   <ul>
--   <li><a>K1</a> - a single value</li>
--   <li><a>M1</a> - a value with some additional metadata (which we simply
--   discard)</li>
--   <li><a>:+:</a> - sum types</li>
--   <li><a>:*:</a> - product types</li>
--   </ul>
class PartialSemigroupRep rep
repPartialSemigroupOp :: PartialSemigroupRep rep => rep a -> rep a -> Maybe (rep a)

-- | Representable types of kind *. This class is derivable in GHC with the
--   DeriveGeneric flag on.
class Generic a

-- | A <a>PartialSemigroup</a> is like a <a>Semigroup</a>, but with an
--   operator returning <tt><a>Maybe</a> a</tt> rather than <tt>a</tt>.
--   
--   For comparison:
--   
--   <pre>
--   (<a>&lt;&gt;</a>)  :: <a>Semigroup</a> a        =&gt; a -&gt; a -&gt; a
--   (<a>&lt;&gt;?</a>) :: <a>PartialSemigroup</a> a =&gt; a -&gt; a -&gt; <a>Maybe</a> a
--   </pre>
--   
--   <h3>The associativity axiom for partial semigroups</h3>
--   
--   For all <tt>x</tt>, <tt>y</tt>, <tt>z</tt>:
--   
--   <ul>
--   <li>If <tt>x <a>&lt;&gt;?</a> y = <a>Just</a> xy</tt> and <tt>y
--   <a>&lt;&gt;?</a> z = <a>Just</a> yz</tt>, then<ul><li><tt>x
--   <a>&lt;&gt;?</a> yz = xy <a>&lt;&gt;?</a> z</tt>.</li></ul></li>
--   </ul>
--   
--   <h4>Relationship to the semigroup associativity axiom</h4>
--   
--   The partial semigroup associativity axiom is a natural adaptation of
--   the semigroup associativity axiom
--   
--   <pre>
--   x <a>&lt;&gt;</a> (y <a>&lt;&gt;</a> z) = (x <a>&lt;&gt;</a> y) <a>&lt;&gt;</a> z
--   </pre>
--   
--   with a slight modification to accommodate situations where
--   <a>&lt;&gt;</a> is undefined. We may gain some insight into the
--   connection between <a>Semigroup</a> and <a>PartialSemigroup</a> by
--   rephrasing the partial semigroup associativity in terms of a partial
--   <a>&lt;&gt;</a> operator thusly:
--   
--   For all <tt>x</tt>, <tt>y</tt>, <tt>z</tt>:
--   
--   <ul>
--   <li>If <tt>x <a>&lt;&gt;</a> y</tt> and <tt>y <a>&lt;&gt;</a> z</tt>
--   are both defined, then<ul><li><tt>x <a>&lt;&gt;</a> (y <a>&lt;&gt;</a>
--   z)</tt> is defined if and only if <tt>(x <a>&lt;&gt;</a> y)
--   <a>&lt;&gt;</a> z</tt> is defined, and</li><li>if these things
--   <i>are</i> all defined, then the axiom for total semigroups <tt>x
--   <a>&lt;&gt;</a> (y <a>&lt;&gt;</a> z) = (x <a>&lt;&gt;</a> y)
--   <a>&lt;&gt;</a> z</tt> must hold.</li></ul></li>
--   </ul>
class PartialSemigroup a
(<>?) :: PartialSemigroup a => a -> a -> Maybe a
instance Data.PartialSemigroup.PartialSemigroup a => Data.PartialSemigroup.Generics.PartialSemigroupRep (GHC.Generics.K1 i a)
instance Data.PartialSemigroup.Generics.PartialSemigroupRep rep => Data.PartialSemigroup.Generics.PartialSemigroupRep (GHC.Generics.M1 i meta rep)
instance (Data.PartialSemigroup.Generics.PartialSemigroupRep rep1, Data.PartialSemigroup.Generics.PartialSemigroupRep rep2) => Data.PartialSemigroup.Generics.PartialSemigroupRep (rep1 GHC.Generics.:*: rep2)
instance (Data.PartialSemigroup.Generics.PartialSemigroupRep rep1, Data.PartialSemigroup.Generics.PartialSemigroupRep rep2) => Data.PartialSemigroup.Generics.PartialSemigroupRep (rep1 GHC.Generics.:+: rep2)
