:: (a -> Bool) -> [a] -> [[a]] package:utility-ht

Split the list at the occurrences of a separator into sub-lists. Remove the separators. This is somehow a generalization of lines and words. But note the differences:
>>> words "a  a"
["a","a"]

>>> chop (' '==) "a  a"
["a","","a"]
>>> lines "a\n\na"
["a","","a"]

>>> chop ('\n'==) "a\n\na"
["a","","a"]
>>> lines "a\n"
["a"]

>>> chop ('\n'==) "a\n"
["a",""]
Split the list after each occurence of a terminator. Keep the terminator. There is always a list for the part after the last terminator. It may be empty. See package non-empty for more precise result type.
forAllPredicates $ \p xs -> concat (segmentAfter p xs) == xs
forAllPredicates $ \p xs -> length (filter p xs) == length (tail (segmentAfter p xs))
forAllPredicates $ \p -> all (p . last) . init . segmentAfter p
forAllPredicates $ \p -> all (all (not . p) . init) . init . segmentAfter p
This test captures both infinitely many groups and infinitely big groups:
forAllPredicates $ \p x -> flip seq True . (!!100) . concat . segmentAfter p . cycle . (x:)
Split the list before each occurence of a leading character. Keep these characters. There is always a list for the part before the first leading character. It may be empty. See package non-empty for more precise result type.
>>> segmentBefore isUpper "AbcdXyz"
["","Abcd","Xyz"]

>>> segmentBefore isUpper "kAbcdXYZ"
["k","Abcd","X","Y","Z"]
forAllPredicates $ \p xs -> concat (segmentBefore p xs) == xs
forAllPredicates $ \p xs -> length (filter p xs) == length (tail (segmentBefore p xs))
forAllPredicates $ \p -> all (p . head) . tail . segmentBefore p
forAllPredicates $ \p -> all (all (not . p) . tail) . tail . segmentBefore p
forAllPredicates $ \p x -> flip seq True . (!!100) . concat . segmentBefore p . cycle . (x:)
Divides a list into sublists such that the members in a sublist share the same key. It uses semantics of groupBy, not that of groupBy.