-- 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 (<>?) :: a -- -> a -> Maybe a. -- -- The partial-semigroup-hedgehog companion package provides -- support for checking the partial semigroup associativity axiom using -- the hedgehog package. @package partial-semigroup @version 0.6.0.0 -- | A semigroup (Semigroup) is a set with a binary -- associative operation (<>). This module defines a -- partial semigroup (PartialSemigroup), a semigroup for -- which <> is not required to be defined over all inputs. module Data.PartialSemigroup -- | A PartialSemigroup is like a Semigroup, but with an -- operator returning Maybe a rather than a. -- -- For comparison: -- --
--   (<>)  :: Semigroup a        => a -> a -> a
--   (<>?) :: PartialSemigroup a => a -> a -> Maybe a
--   
-- --

The associativity axiom for partial semigroups

-- -- For all x, y, z: -- -- -- --

Relationship to the semigroup associativity axiom

-- -- The partial semigroup associativity axiom is a natural adaptation of -- the semigroup associativity axiom -- --
--   x <> (y <> z) = (x <> y) <> z
--   
-- -- with a slight modification to accommodate situations where -- <> is undefined. We may gain some insight into the -- connection between Semigroup and PartialSemigroup by -- rephrasing the partial semigroup associativity in terms of a partial -- <> operator thusly: -- -- For all x, y, z: -- -- class PartialSemigroup a (<>?) :: PartialSemigroup a => a -> a -> Maybe a infixr 6 <>? -- | A wrapper for Either where the PartialSemigroup operator -- is defined only over Left values. -- --

Examples

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

Examples

-- -- Two Rights make a Just. -- --
--   >>> AppendRight (Right "ab") <>? AppendRight (Right "cd")
--   Just (AppendRight {unAppendRight = Right "abcd"})
--   
-- -- Anything else produces Nothing -- --
--   >>> AppendRight (Left "ab") <>? AppendRight (Left "cd")
--   Nothing
--   
-- -- groupAndConcat combines consecutive Right values, -- leaving the Left values unmodified. -- --
--   >>> xs = [Left "a", Left "b", Right "c", Right "d", Left "e", Left "f"]
--   
--   >>> fmap unAppendRight . groupAndConcat . fmap AppendRight $ xs
--   [Left "a",Left "b",Right "cd",Left "e",Left "f"]
--   
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. -- --

Examples

-- -- For Either, groupAndConcat combines contiguous sublists -- of Left and contiguous sublists of Right. -- --
--   >>> xs = [Left "a", Right "b", Right "c", Left "d", Left "e", Left "f"]
--   
--   >>> groupAndConcat xs
--   [Left "a",Right "bc",Left "def"]
--   
groupAndConcat :: PartialSemigroup a => [a] -> [a] -- | If xs is nonempty and the partial semigroup operator is -- defined for all pairs of values in xs, then -- partialConcat xs produces a Just result with -- the combination of all the values. Otherwise, returns Nothing. -- --

Examples

-- -- When all values can combine, we get a Just of their -- combination. -- --
--   >>> partialConcat [Left "a", Left "b", Left "c"]
--   Just (Left "abc")
--   
-- -- When some values cannot be combined, we get Nothing. -- --
--   >>> partialConcat [Left "a", Left "b", Right "c"]
--   Nothing
--   
-- -- When the list is empty, we get Nothing. -- --
--   >>> partialConcat []
--   Nothing
--   
partialConcat :: PartialSemigroup a => [a] -> Maybe a -- | Like partialConcat, but for non-empty lists. -- --

Examples

-- -- When all values can combine, we get a Just of their -- combination. -- --
--   >>> partialConcat1 (Left "a" :| [Left "b", Left "c"])
--   Just (Left "abc")
--   
-- -- When some values cannot be combined, we get Nothing. -- --
--   >>> partialConcat1 (Left "a" :| [Left "b", Right "c"])
--   Nothing
--   
partialConcat1 :: PartialSemigroup a => NonEmpty a -> Maybe a -- |

Examples

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

Examples

-- -- If lists are the same length and each pair of elements successfully, -- then we get a Just result. -- --
--   >>> xs = Left "a" :| [Left "b", Right "c"]
--   
--   >>> ys = Left "1" :| [Left "2", Right "3"]
--   
--   >>> partialZip1 xs ys
--   Just (Left "a1" :| [Left "b2",Right "c3"])
--   
-- -- If the pairs do not all combine, then we get Nothing. -- --
--   >>> xs = Left "a" :| [Left "b", Right "c"]
--   
--   >>> ys = Left "1" :| [Right "2", Right "3"]
--   
--   >>> partialZip1 xs ys
--   Nothing
--   
-- -- If the lists have different lengths, then we get Nothing. -- --
--   >>> xs = Left "a" :| [Left "b", Right "c"]
--   
--   >>> ys = Left "1" :| [Left "2"]
--   
--   >>> partialZip1 xs ys
--   Nothing
--   
partialZip1 :: PartialSemigroup a => NonEmpty a -> NonEmpty a -> Maybe (NonEmpty a) -- | A wrapper to turn any value with a Semigroup instance into a -- value with a PartialSemigroup instance whose <>? -- operator always returns Just. -- --

Examples

-- --
--   >>> Total "ab" <>? Total "cd"
--   Just (Total {unTotal = "abcd"})
--   
-- --
--   >>> f = getProduct . unTotal
--   
--   >>> g = Total . Product
--   
--   >>> fmap f . partialConcat . fmap g $ [1..4]
--   Just 24
--   
newtype Total a Total :: a -> Total a [unTotal] :: Total a -> a -- | A wrapper for Maybe with an error-propagating Semigroup. newtype Partial a Partial :: Maybe a -> Partial a [unPartial] :: Partial a -> Maybe a -- | A partial semigroup operation which always fails. newtype One a One :: a -> One a [theOne] :: One a -> a -- | A wrapper for Maybe whose partial semigroup operation fails -- when two Justs are combined. newtype AtMostOne a AtMostOne :: Maybe a -> AtMostOne a [theOneMaybe] :: AtMostOne a -> Maybe 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 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 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 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 (Data.PartialSemigroup.One a) instance GHC.Read.Read a => GHC.Read.Read (Data.PartialSemigroup.One a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.PartialSemigroup.One a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.PartialSemigroup.One a) instance GHC.Show.Show a => GHC.Show.Show (Data.PartialSemigroup.AtMostOne a) instance GHC.Read.Read a => GHC.Read.Read (Data.PartialSemigroup.AtMostOne a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.PartialSemigroup.AtMostOne a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.PartialSemigroup.AtMostOne a) instance Data.PartialSemigroup.PartialSemigroup (Data.PartialSemigroup.AtMostOne a) instance Data.PartialSemigroup.PartialSemigroup (Data.PartialSemigroup.One 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 GHC.Base.Semigroup a => Data.PartialSemigroup.PartialSemigroup (Data.PartialSemigroup.Total a) instance Data.PartialSemigroup.PartialSemigroup a => GHC.Base.Semigroup (Data.PartialSemigroup.Partial a) instance Data.PartialSemigroup.PartialSemigroup () instance Data.PartialSemigroup.PartialSemigroup [a] instance GHC.Num.Num a => Data.PartialSemigroup.PartialSemigroup (Data.Semigroup.Internal.Sum a) instance GHC.Num.Num a => Data.PartialSemigroup.PartialSemigroup (Data.Semigroup.Internal.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 Generic and all of its fields have -- PartialSemigroup instances, you can get a -- PartialSemigroup for free using -- genericPartialSemigroupOp. -- --

Example

-- -- For this demonstration we'll define a contrived example type -- T with two constructors, A and B. -- --
--   >>> data T = A String (Either String String) | B String deriving (Generic, Show)
--   
-- -- And then define its PartialSemigroup instance using -- genericPartialSemigroupOp. -- --
--   >>> instance PartialSemigroup T where (<>?) = genericPartialSemigroupOp
--   
-- -- This gives us an implementation of <>? which combines -- values only if they have the same structure. -- --
--   >>> A "s" (Left "x") <>? A "t" (Left "y")
--   Just (A "st" (Left "xy"))
--   
-- --
--   >>> B "x" <>? B "y"
--   Just (B "xy")
--   
-- -- For values that do not have the same structure, -- <>? produces Nothing. -- --
--   >>> A "s" (Left "x") <>? A "t" (Right "y")
--   Nothing
--   
-- --
--   >>> A "x" (Left "y") <>? B "z"
--   Nothing
--   
module Data.PartialSemigroup.Generics genericPartialSemigroupOp :: (Generic a, PartialSemigroupRep (Rep a)) => a -> a -> Maybe a -- | The class of generic type Reps for which we can automatically -- derive PartialSemigroup: -- -- 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. -- -- A Generic instance must satisfy the following laws: -- --
--   from . toid
--   to . fromid
--   
class Generic a -- | A PartialSemigroup is like a Semigroup, but with an -- operator returning Maybe a rather than a. -- -- For comparison: -- --
--   (<>)  :: Semigroup a        => a -> a -> a
--   (<>?) :: PartialSemigroup a => a -> a -> Maybe a
--   
-- --

The associativity axiom for partial semigroups

-- -- For all x, y, z: -- -- -- --

Relationship to the semigroup associativity axiom

-- -- The partial semigroup associativity axiom is a natural adaptation of -- the semigroup associativity axiom -- --
--   x <> (y <> z) = (x <> y) <> z
--   
-- -- with a slight modification to accommodate situations where -- <> is undefined. We may gain some insight into the -- connection between Semigroup and PartialSemigroup by -- rephrasing the partial semigroup associativity in terms of a partial -- <> operator thusly: -- -- For all x, y, z: -- -- class PartialSemigroup a (<>?) :: PartialSemigroup a => a -> a -> Maybe a infixr 6 <>? 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)