úÎ!UêR8      !"#$%&'()*+,-./01234567SafeM  partial-semigroupA wrapper for 8 where the   operator is defined only over 9 values.ExamplesTwo 9 s make a :.5AppendRight (Right "ab") <>? AppendRight (Right "cd")1Just (AppendRight {unAppendRight = Right "abcd"})Anything else produces ;3AppendRight (Left "ab") <>? AppendRight (Left "cd")Nothing combines consecutive 9 values, leaving the < values unmodified.Cxs = [Left "a", Left "b", Right "c", Right "d", Left "e", Left "f"];fmap unAppendRight . groupAndConcat . fmap AppendRight $ xs0[Left "a",Left "b",Right "cd",Left "e",Left "f"]partial-semigroupA wrapper for 8 where the   operator is defined only over < values.ExamplesTwo < s make a :.1AppendLeft (Left "ab") <>? AppendLeft (Left "cd").Just (AppendLeft {unAppendLeft = Left "abcd"})Anything else produces ;3AppendLeft (Right "ab") <>? AppendLeft (Right "cd")Nothing combines consecutive < values, leaving the 9 values unmodified.Cxs = [Left "a", Left "b", Right "c", Right "d", Left "e", Left "f"]9fmap unAppendLeft . groupAndConcat . fmap AppendLeft $ xs)[Left "ab",Right "c",Right "d",Left "ef"]partial-semigroup#A wrapper to turn any value with a = instance into a value with a   instance whose  operator always returns :.ExamplesTotal "ab" <>? Total "cd"Just (Total {unTotal = "abcd"})f = getProduct . unTotalg = Total . Product(fmap f . partialConcat . fmap g $ [1..4]Just 24 partial-semigroupA wrapper for > with an error-propagating =. partial-semigroupA   is like a =!, but with an operator returning > a rather than a.For comparison: (?) :: = a => a -> a -> a () ::   a => a -> a -> > a .The associativity axiom for partial semigroupsFor all x, y, z:If x  y = : xy and y  z = : yz, thenx  yz = xy  z.1Relationship to the semigroup associativity axiomfThe 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 ?D is undefined. We may gain some insight into the connection between = and  I by rephrasing the partial semigroup associativity in terms of a partial ? operator thusly:For all x, y, z:If x ? y and y ? z are both defined, thenx ? (y ? z) is defined if and only if (x ? y) ? z is defined, andif these things are4 all defined, then the axiom for total semigroups x ? (y ? z) = (x ? y) ? z must hold.partial-semigroupyApply a semigroup operation to any pairs of consecutive list elements where the semigroup operation is defined over them.ExamplesFor 8, ! combines contiguous sublists of < and contiguous sublists of 9.Cxs = [Left "a", Right "b", Right "c", Left "d", Left "e", Left "f"]groupAndConcat xs [Left "a",Right "bc",Left "def"]partial-semigroupIf xsV is nonempty and the partial semigroup operator is defined for all pairs of values in xs, then  xs produces a :C result with the combination of all the values. Otherwise, returns ;.Examples&When all values can combine, we get a : of their combination.,partialConcat [Left "a", Left "b", Left "c"]Just (Left "abc"),When some values cannot be combined, we get ;.-partialConcat [Left "a", Left "b", Right "c"]NothingWhen the list is empty, we get ;.partialConcat []Nothingpartial-semigroupLike , but for non-empty lists.Examples&When all values can combine, we get a : of their combination.1partialConcat1 (Left "a" :| [Left "b", Left "c"])Just (Left "abc"),When some values cannot be combined, we get ;.2partialConcat1 (Left "a" :| [Left "b", Right "c"])Nothingpartial-semigroupExamplesSIf lists are the same length and each pair of elements successfully, then we get a : 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 ;.$xs = [Left "a", Left "b", Right "c"]%ys = [Left "1", Right "2", Right "3"]partialZip xs ysNothing1If the lists have different lengths, then we get ;.$xs = [Left "a", Left "b", Right "c"]ys = [Left "1", Left "2"]partialZip xs ysNothingpartial-semigroupLike , but for non-empty lists.ExamplesSIf lists are the same length and each pair of elements successfully, then we get a : 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 ;.&xs = Left "a" :| [Left "b", Right "c"]'ys = Left "1" :| [Right "2", Right "3"]partialZip1 xs ysNothing1If the lists have different lengths, then we get ;.&xs = Left "a" :| [Left "b", Right "c"]ys = Left "1" :| [Left "2"]partialZip1 xs ysNothingpartial-semigroup   6Safe<STQè1partial-semigroupThe class of generic type @(s for which we can automatically derive  :A - a single valueBB - a value with some additional metadata (which we simply discard)C - sum typesD - product types 123312 E        !"#$%&'()*+,-./0123456789:9;<=<>9?<@<A<BCDEFGH0partial-semigroup-0.4.0.0-9xCaVRL5nj56BRMhNv8nNeData.PartialSemigroup.GenericsData.PartialSemigroupbase GHC.GenericsGeneric AppendRight unAppendRight AppendLeft unAppendLeftTotalunTotalPartial unPartialPartialSemigroup<>?groupAndConcat partialConcatpartialConcat1 partialZip partialZip1$fPartialSemigroupZipList$fPartialSemigroup(,,)$fPartialSemigroup(,)$fPartialSemigroupEither$fPartialSemigroupIdentity$fPartialSemigroupProduct$fPartialSemigroupSum$fPartialSemigroup[]$fPartialSemigroup()$fSemigroupPartial$fPartialSemigroupTotal$fPartialSemigroupAppendLeft$fPartialSemigroupAppendRight $fEqPartial $fOrdPartial $fReadPartial $fShowPartial $fEqTotal $fOrdTotal $fReadTotal $fShowTotal$fEqAppendLeft$fOrdAppendLeft$fReadAppendLeft$fShowAppendLeft$fEqAppendRight$fOrdAppendRight$fReadAppendRight$fShowAppendRightPartialSemigroupReprepPartialSemigroupOpgenericPartialSemigroupOp$fPartialSemigroupRep:+:$fPartialSemigroupRep:*:$fPartialSemigroupRepM1$fPartialSemigroupRepK1 Data.EitherEitherRightGHC.BaseJustNothingLeft SemigroupMaybe<>RepK1M1:+::*: