:: [a] -> [a] -> [[a]] is:exact

manyTill p end applies action p zero or more times until action end succeeds, and returns the list of values returned by p. This can be used to scan comments:
simpleComment   = string "<!--" *> manyTill anyChar (string "-->")
(Note the overlapping parsers anyChar and string "-->". While this will work, it is not very efficient, as it will cause a lot of backtracking.)
manyTill' p end applies action p zero or more times until action end succeeds, and returns the list of values returned by p. This can be used to scan comments:
simpleComment   = string "<!--" *> manyTill' anyChar (string "-->")
(Note the overlapping parsers anyChar and string "-->". While this will work, it is not very efficient, as it will cause a lot of backtracking.) The value returned by p is forced to WHNF.
sepBy p sep applies zero or more occurrences of p, separated by sep. Returns a list of the values returned by p.
commaSep p  = p `sepBy` (char ',')
sepBy1 p sep applies one or more occurrences of p, separated by sep. Returns a list of the values returned by p.
commaSep p  = p `sepBy1` (char ',')
sepBy' p sep applies zero or more occurrences of p, separated by sep. Returns a list of the values returned by p. The value returned by p is forced to WHNF.
commaSep p  = p `sepBy'` (char ',')
sepBy1' p sep applies one or more occurrences of p, separated by sep. Returns a list of the values returned by p. The value returned by p is forced to WHNF.
commaSep p  = p `sepBy1'` (char ',')
Split on the given sublist. Equivalent to split . dropDelims . onSublist.
>>> splitOn ":" "12:35:07"
["12","35","07"]
>>> splitOn "x" "axbxc"
["a","b","c"]
>>> splitOn "x" "axbxcx"
["a","b","c",""]
>>> splitOn ".." "a..b...c....d.."
["a","b",".c","","d",""]
In some parsing combinator frameworks this is also known as sepBy. Note that this is the right inverse of the intercalate function from Data.List, that is,
intercalate x . splitOn x === id
splitOn x . intercalate x is the identity on certain lists, but it is tricky to state the precise conditions under which this holds. (For example, it is not enough to say that x does not occur in any elements of the input list. Working out why is left as an exercise for the reader.)
Split on any of the given elements. Equivalent to split . dropDelims . oneOf.
>>> splitOneOf ";.," "foo,bar;baz.glurk"
["foo","bar","baz","glurk"]
Split into chunks terminated by the given subsequence. Equivalent to split . dropFinalBlank . dropDelims . onSublist.
>>> endBy ".;" "foo.;bar.;baz.;"
["foo","bar","baz"]
Note also that the lines function from Data.List is equivalent to endBy "\n".
Split into chunks terminated by one of the given elements. Equivalent to split . dropFinalBlank . dropDelims . oneOf.
>>> endByOneOf ";," "foo;bar,baz;"
["foo","bar","baz"]
Split a list into chunks of the given lengths.
>>> splitPlaces [2,3,4] [1..20]
[[1,2],[3,4,5],[6,7,8,9]]
>>> splitPlaces [4,9] [1..10]
[[1,2,3,4],[5,6,7,8,9,10]]
>>> splitPlaces [4,9,3] [1..10]
[[1,2,3,4],[5,6,7,8,9,10]]
If the input list is longer than the total of the given lengths, then the remaining elements are dropped. If the list is shorter than the total of the given lengths, then the result may contain fewer chunks than requested, and the last chunk may be shorter than requested.
Split a list into chunks of the given lengths. Unlike splitPlaces, the output list will always be the same length as the first input argument. If the input list is longer than the total of the given lengths, then the remaining elements are dropped. If the list is shorter than the total of the given lengths, then the last several chunks will be shorter than requested or empty.
>>> splitPlacesBlanks [2,3,4] [1..20]
[[1,2],[3,4,5],[6,7,8,9]]
>>> splitPlacesBlanks [4,9] [1..10]
[[1,2,3,4],[5,6,7,8,9,10]]
>>> splitPlacesBlanks [4,9,3] [1..10]
[[1,2,3,4],[5,6,7,8,9,10],[]]
Notice the empty list in the output of the third example, which differs from the behavior of splitPlaces.