>>> group "Mississippi" ["M","i","ss","i","ss","i","pp","i"]
>>> group [1, 1, 1, 2, 2, 3, 4, 5, 5] [[1,1,1],[2,2],[3],[4],[5,5]]
>>> group "Mississippi" ['M' :| "",'i' :| "",'s' :| "s",'i' :| "",'s' :| "s",'i' :| "",'p' :| "p",'i' :| ""]
>>> groupBy (\a b -> b - a < 5) [0..19] [[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14],[15,16,17,18,19]]It's often preferable to use Data.List.NonEmpty.groupBy, which provides type-level guarantees of non-emptiness of inner lists.
>>> groupBy (/=) [1, 1, 1, 2, 3, 1, 4, 4, 5] [[1],[1],[1,2,3],[1,4,4,5]]
>>> groupBy (>) [1, 3, 5, 1, 4, 2, 6, 5, 4] [[1],[3],[5,1,4,2],[6,5,4]]
>>> groupBy (const not) [True, False, True, False, False, False, True] [[True,False],[True,False,False,False],[True]]
(a <> b) <> c == a <> (b <> c)
>>> Min 1 <> Min 2 <> Min 3 <> Min 4 :: Min Int Min {getMin = 1}If we need to combine multiple values we can use the sconcat function to do so. We need to ensure however that we have at least one value to operate on, since otherwise our result would be undefined. It is for this reason that sconcat uses Data.List.NonEmpty.NonEmpty - a list that can never be empty:
>>> (1 :| []) 1 :| []
>>> (1 :| [2, 3, 4]) 1 :| [2,3,4]
>>> sconcat (1 :| [2, 3, 4]) :: Min Int Min {getMin = 1}
>>> sconcat (1 :| [2, 3, 4]) :: Max Int Max {getMax = 4}String concatenation is another example of a Semigroup instance:
>>> "foo" <> "bar" "foobar"A Semigroup is a generalization of a Monoid. Yet unlike the Semigroup, the Monoid requires the presence of a neutral element (mempty) in addition to the associative operator. The requirement for a neutral element prevents many types from being a full Monoid, like Data.List.NonEmpty.NonEmpty. Note that the use of (<>) in this module conflicts with an operator with the same name that is being exported by Data.Monoid. However, this package re-exports (most of) the contents of Data.Monoid, so to use semigroups and monoids in the same package just
import Data.Semigroup