| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Data.PartialSemigroup
- class PartialSemigroup a where
- newtype AppendLeft a b = AppendLeft {
- unAppendLeft :: Either a b
- newtype AppendRight a b = AppendRight {
- unAppendRight :: Either a b
- groupAndConcat :: forall a. PartialSemigroup a => [a] -> [a]
- partialConcat :: forall a. PartialSemigroup a => [a] -> Maybe a
- partialConcat1 :: forall a. PartialSemigroup a => NonEmpty a -> Maybe a
- partialZip :: forall a. PartialSemigroup a => [a] -> [a] -> Maybe [a]
- partialZip1 :: forall a. PartialSemigroup a => NonEmpty a -> NonEmpty a -> Maybe (NonEmpty a)
- newtype Total a = Total {
- unTotal :: a
- newtype Partial a = Partial {}
Partial semigroup
class PartialSemigroup a where Source #
A partial semigroup is like a Semigroup, but with an operator returning
rather than Maybe aa.
For comparison:
(<>) :: Semigroup a => a -> a -> a appendMaybe :: PartialSemigroup a => a -> a -> Maybe a
The associative law for partial semigroups
For all x, y, z such that appendMaybe x y = Just xy and
appendMaybe y z = Just yx, appendMaybe x yz = appendMaybe xy z.
Minimal complete definition
Methods
appendMaybe :: a -> a -> Maybe a Source #
Instances
| PartialSemigroup () Source # | |
| PartialSemigroup [a] Source # | |
| PartialSemigroup a => PartialSemigroup (Identity a) Source # | |
| PartialSemigroup a => PartialSemigroup (ZipList a) Source # | |
| Num a => PartialSemigroup (Sum a) Source # | |
| Num a => PartialSemigroup (Product a) Source # | |
| Semigroup a => PartialSemigroup (Total a) Source # | |
| (PartialSemigroup a, PartialSemigroup b) => PartialSemigroup (Either a b) Source # | |
| (PartialSemigroup a, PartialSemigroup b) => PartialSemigroup (a, b) Source # | |
| PartialSemigroup b => PartialSemigroup (AppendRight a b) Source # | |
| PartialSemigroup a => PartialSemigroup (AppendLeft a b) Source # | |
| (PartialSemigroup a, PartialSemigroup b, PartialSemigroup c) => PartialSemigroup (a, b, c) Source # | |
Either
The exemplary nontrivial PartialSemigroup is Either, for which the append
operator produces a Just result only if both arguments are Left or both
arguments are Right.
>>>appendMaybe (Left "ab") (Left "cd")Just (Left "abcd")
>>>appendMaybe (Left "ab") (Right [1,2])Nothing
newtype AppendLeft a b Source #
A wrapper for Either where the PartialSemigroup operator is defined
only over Left values.
Examples
>>>appendMaybe (AppendLeft (Left "ab")) (AppendLeft (Left "cd"))Just (AppendLeft {unAppendLeft = Left "abcd"})
Anything else produces Nothing
>>>appendMaybe (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"]
Constructors
| AppendLeft | |
Fields
| |
Instances
| (Eq a, Eq b) => Eq (AppendLeft a b) Source # | |
| (Ord a, Ord b) => Ord (AppendLeft a b) Source # | |
| (Read a, Read b) => Read (AppendLeft a b) Source # | |
| (Show a, Show b) => Show (AppendLeft a b) Source # | |
| PartialSemigroup a => PartialSemigroup (AppendLeft a b) Source # | |
newtype AppendRight a b Source #
A wrapper for Either where the PartialSemigroup operator is defined
only over Right values.
Examples
>>>appendMaybe (AppendRight (Right "ab")) (AppendRight (Right "cd"))Just (AppendRight {unAppendRight = Right "abcd"})
Anything else produces Nothing
>>>appendMaybe (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"]
Constructors
| AppendRight | |
Fields
| |
Instances
| (Eq a, Eq b) => Eq (AppendRight a b) Source # | |
| (Ord a, Ord b) => Ord (AppendRight a b) Source # | |
| (Read a, Read b) => Read (AppendRight a b) Source # | |
| (Show a, Show b) => Show (AppendRight a b) Source # | |
| PartialSemigroup b => PartialSemigroup (AppendRight a b) Source # | |
Tuples
A tuple forms a partial semigroups when all of its constituent parts have
partial semigroups. The append operator returns a Just value when all of the
fields' append operators must return Just values.
>>>x = (Left "ab", Right "hi")>>>y = (Left "cd", Right "jk")>>>appendMaybe x yJust (Left "abcd",Right "hijk")
>>>x = (Left "ab", Right "hi")>>>y = (Left "cd", Left "jk")>>>appendMaybe x yNothing
Concatenation
groupAndConcat :: forall a. PartialSemigroup a => [a] -> [a] Source #
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"]
partialConcat :: forall a. PartialSemigroup a => [a] -> Maybe a Source #
If xs is nonempty and the partial semigroup operator is defined for all
pairs of values in xs, then produces a partialConcat xsJust 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
partialConcat1 :: forall a. PartialSemigroup a => NonEmpty a -> Maybe a Source #
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
Zipping
partialZip :: forall a. PartialSemigroup a => [a] -> [a] -> Maybe [a] Source #
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 ysJust [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 ysNothing
If the lists have different lengths, then we get Nothing.
>>>xs = [Left "a", Left "b", Right "c"]>>>ys = [Left "1", Left "2"]>>>partialZip xs ysNothing
partialZip1 :: forall a. PartialSemigroup a => NonEmpty a -> NonEmpty a -> Maybe (NonEmpty a) Source #
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 ysJust (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 ysNothing
If the lists have different lengths, then we get Nothing.
>>>xs = Left "a" :| [Left "b", Right "c"]>>>ys = Left "1" :| [Left "2"]>>>partialZip1 xs ysNothing
Total semigroups
Every type with a Semigroup can be given a trivial PartialSemigroup instance
defined as:
appendMaybex y =Just(x <> y)
Additionally, any type with a Semigroup can be treated as a PartialSemigroup
by lifting it into Total.
A wrapper to turn any value with a Semigroup instance into a value with a
PartialSemigroup instance whose appendMaybe operator always returns Just.
Examples
>>>appendMaybe (Total "ab") (Total "cd")Just (Total {unTotal = "abcd"})
>>>f = getProduct . unTotal>>>g = Total . Product>>>fmap f . partialConcat . fmap g $ [1..4]Just 24