-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Combinator library for splitting lists.
--   
--   Combinator library and utility functions for splitting lists.
@package split
@version 0.1.4.3


-- | Implementation module for <a>Data.List.Split</a>, a combinator library
--   for splitting lists. See the <a>Data.List.Split</a> documentation for
--   more description and examples.
module Data.List.Split.Internals

-- | A splitting strategy.
data Splitter a
Splitter :: Delimiter a -> DelimPolicy -> CondensePolicy -> EndPolicy -> EndPolicy -> Splitter a

-- | What delimiter to split on
delimiter :: Splitter a -> Delimiter a

-- | What to do with delimiters (drop from output, keep as separate
--   elements in output, or merge with previous or following chunks)
delimPolicy :: Splitter a -> DelimPolicy

-- | What to do with multiple consecutive delimiters
condensePolicy :: Splitter a -> CondensePolicy

-- | Drop an initial blank?
initBlankPolicy :: Splitter a -> EndPolicy

-- | Drop a final blank?
finalBlankPolicy :: Splitter a -> EndPolicy

-- | The default splitting strategy: keep delimiters in the output as
--   separate chunks, don't condense multiple consecutive delimiters into
--   one, keep initial and final blank chunks. Default delimiter is the
--   constantly false predicate.
--   
--   Note that <a>defaultSplitter</a> should normally not be used; use
--   <a>oneOf</a>, <a>onSublist</a>, or <a>whenElt</a> instead, which are
--   the same as the <a>defaultSplitter</a> with just the delimiter
--   overridden.
--   
--   The <a>defaultSplitter</a> strategy with any delimiter gives a
--   maximally information-preserving splitting strategy, in the sense that
--   (a) taking the <a>concat</a> of the output yields the original list,
--   and (b) given only the output list, we can reconstruct a
--   <a>Splitter</a> which would produce the same output list again given
--   the original input list. This default strategy can be overridden to
--   allow discarding various sorts of information.
defaultSplitter :: Splitter a

-- | A delimiter can either be a predicate on elements, or a list of
--   elements to be matched as a subsequence.
data Delimiter a
DelimEltPred :: (a -> Bool) -> Delimiter a
DelimSublist :: [a] -> Delimiter a

-- | Try to match a delimiter at the start of a list, either failing or
--   decomposing the list into the portion which matched the delimiter and
--   the remainder.
matchDelim :: Delimiter a -> [a] -> Maybe ([a], [a])

-- | What to do with delimiters?
data DelimPolicy

-- | Drop delimiters from the output.
Drop :: DelimPolicy

-- | Keep delimiters as separate chunks of the output.
Keep :: DelimPolicy

-- | Keep delimiters in the output, prepending them to the following chunk.
KeepLeft :: DelimPolicy

-- | Keep delimiters in the output, appending them to the previous chunk.
KeepRight :: DelimPolicy

-- | What to do with multiple consecutive delimiters?
data CondensePolicy

-- | Condense into a single delimiter.
Condense :: CondensePolicy

-- | Insert blank chunks between consecutive delimiters.
KeepBlankFields :: CondensePolicy

-- | What to do with a blank chunk at either end of the list (i.e. when the
--   list begins or ends with a delimiter).
data EndPolicy
DropBlank :: EndPolicy
KeepBlank :: EndPolicy

-- | Tag chunks as delimiters or text.
data Chunk a
Delim :: [a] -> Chunk a
Text :: [a] -> Chunk a

-- | Internal representation of a split list that tracks which pieces are
--   delimiters and which aren't.
type SplitList a = [Chunk a]

-- | Untag a <a>Chunk</a>.
fromElem :: Chunk a -> [a]

-- | Test whether a <a>Chunk</a> is a delimiter.
isDelim :: Chunk a -> Bool

-- | Test whether a <a>Chunk</a> is text.
isText :: Chunk a -> Bool

-- | Given a delimiter to use, split a list into an internal representation
--   with chunks tagged as delimiters or text. This transformation is
--   lossless; in particular, <tt><a>concatMap</a> <a>fromElem</a>
--   (<a>splitInternal</a> d l) == l</tt>.
splitInternal :: Delimiter a -> [a] -> SplitList a
breakDelim :: Delimiter a -> [a] -> ([a], Maybe ([a], [a]))
matchSublist :: Eq a => [a] -> [a] -> Maybe [a]

-- | Given a split list in the internal tagged representation, produce a
--   new internal tagged representation corresponding to the final output,
--   according to the strategy defined by the given <a>Splitter</a>.
postProcess :: Splitter a -> SplitList a -> SplitList a

-- | Drop delimiters if the <a>DelimPolicy</a> is <a>Drop</a>.
doDrop :: DelimPolicy -> SplitList a -> SplitList a

-- | Condense multiple consecutive delimiters into one if the
--   <a>CondensePolicy</a> is <a>Condense</a>.
doCondense :: CondensePolicy -> SplitList a -> SplitList a

-- | Insert blank chunks between any remaining consecutive delimiters, and
--   at the beginning or end if the first or last element is a delimiter.
insertBlanks :: SplitList a -> SplitList a

-- | Insert blank chunks between consecutive delimiters.
insertBlanks' :: SplitList a -> SplitList a

-- | Merge delimiters into adjacent chunks according to the
--   <a>DelimPolicy</a>.
doMerge :: DelimPolicy -> SplitList a -> SplitList a

-- | Merge delimiters with adjacent chunks to the right (yes, that's not a
--   typo: the delimiters should end up on the left of the chunks, so they
--   are merged with chunks to their right).
mergeLeft :: SplitList a -> SplitList a

-- | Merge delimiters with adjacent chunks to the left.
mergeRight :: SplitList a -> SplitList a

-- | Drop an initial blank chunk according to the given <a>EndPolicy</a>.
dropInitial :: EndPolicy -> SplitList a -> SplitList a

-- | Drop a final blank chunk according to the given <a>EndPolicy</a>.
dropFinal :: EndPolicy -> SplitList a -> SplitList a

-- | Split a list according to the given splitting strategy. This is how to
--   "run" a <a>Splitter</a> that has been built using the other
--   combinators.
split :: Splitter a -> [a] -> [[a]]

-- | A splitting strategy that splits on any one of the given elements. For
--   example:
--   
--   <pre>
--   split (oneOf "xyz") "aazbxyzcxd" == ["aa","z","b","x","","y","","z","c","x","d"]
--   </pre>
oneOf :: Eq a => [a] -> Splitter a

-- | A splitting strategy that splits on the given list, when it is
--   encountered as an exact subsequence. For example:
--   
--   <pre>
--   split (onSublist "xyz") "aazbxyzcxd" == ["aazb","xyz","cxd"]
--   </pre>
--   
--   Note that splitting on the empty list is a special case, which splits
--   just before every element of the list being split. For example:
--   
--   <pre>
--   split (onSublist "") "abc" == ["","","a","","b","","c"]
--   split (dropDelims . dropBlanks $ onSublist "") "abc" == ["a","b","c"]
--   </pre>
--   
--   However, if you want to break a list into singleton elements like
--   this, you are better off using <tt><a>splitEvery</a> 1</tt>, or better
--   yet, <tt><a>map</a> (:[])</tt>.
onSublist :: Eq a => [a] -> Splitter a

-- | A splitting strategy that splits on any elements that satisfy the
--   given predicate. For example:
--   
--   <pre>
--   split (whenElt (&lt;0)) [2,4,-3,6,-9,1] == [[2,4],[-3],[6],[-9],[1]]
--   </pre>
whenElt :: (a -> Bool) -> Splitter a

-- | Drop delimiters from the output (the default is to keep them). For
--   example,
--   
--   <pre>
--   split (oneOf ":") "a:b:c" == ["a", ":", "b", ":", "c"]
--   split (dropDelims $ oneOf ":") "a:b:c" == ["a", "b", "c"]
--   </pre>
dropDelims :: Splitter a -> Splitter a

-- | Keep delimiters in the output by prepending them to adjacent chunks.
--   For example:
--   
--   <pre>
--   split (keepDelimsL $ oneOf "xyz") "aazbxyzcxd" == ["aa","zb","x","y","zc","xd"]
--   </pre>
keepDelimsL :: Splitter a -> Splitter a

-- | Keep delimiters in the output by appending them to adjacent chunks.
--   For example:
--   
--   <pre>
--   split (keepDelimsR $ oneOf "xyz") "aazbxyzcxd" == ["aaz","bx","y","z","cx","d"]
--   </pre>
keepDelimsR :: Splitter a -> Splitter a

-- | Condense multiple consecutive delimiters into one. For example:
--   
--   <pre>
--   split (condense $ oneOf "xyz") "aazbxyzcxd" == ["aa","z","b","xyz","c","x","d"]
--   split (dropDelims $ oneOf "xyz") "aazbxyzcxd" == ["aa","b","","","c","d"]
--   split (condense . dropDelims $ oneOf "xyz") "aazbxyzcxd" == ["aa","b","c","d"]
--   </pre>
condense :: Splitter a -> Splitter a

-- | Don't generate a blank chunk if there is a delimiter at the beginning.
--   For example:
--   
--   <pre>
--   split (oneOf ":") ":a:b" == ["",":","a",":","b"]
--   split (dropInitBlank $ oneOf ":") ":a:b" == [":","a",":","b"]
--   </pre>
dropInitBlank :: Splitter a -> Splitter a

-- | Don't generate a blank chunk if there is a delimiter at the end. For
--   example:
--   
--   <pre>
--   split (oneOf ":") "a:b:" == ["a",":","b",":",""]
--   split (dropFinalBlank $ oneOf ":") "a:b:" == ["a",":","b",":"]
--   </pre>
dropFinalBlank :: Splitter a -> Splitter a

-- | Drop all blank chunks from the output. Equivalent to
--   <tt><a>dropInitBlank</a> . <a>dropFinalBlank</a> .
--   <a>condense</a></tt>. For example:
--   
--   <pre>
--   split (oneOf ":") "::b:::a" == ["",":","",":","b",":","",":","",":","a"]
--   split (dropBlanks $ oneOf ":") "::b:::a" == ["::","b",":::","a"]
--   </pre>
dropBlanks :: Splitter a -> Splitter a

-- | Make a strategy that splits a list into chunks that all start with the
--   given subsequence (except possibly the first). Equivalent to
--   <tt><a>dropInitBlank</a> . <a>keepDelimsL</a> . <a>onSublist</a></tt>.
--   For example:
--   
--   <pre>
--   split (startsWith "app") "applyapplicativeapplaudapproachapple" == ["apply","applicative","applaud","approach","apple"]
--   </pre>
startsWith :: Eq a => [a] -> Splitter a

-- | Make a strategy that splits a list into chunks that all start with one
--   of the given elements (except possibly the first). Equivalent to
--   <tt><a>dropInitBlank</a> . <a>keepDelimsL</a> . <a>oneOf</a></tt>. For
--   example:
--   
--   <pre>
--   split (startsWithOneOf ['A'..'Z']) "ACamelCaseIdentifier" == ["A","Camel","Case","Identifier"]
--   </pre>
startsWithOneOf :: Eq a => [a] -> Splitter a

-- | Make a strategy that splits a list into chunks that all end with the
--   given subsequence, except possibly the last. Equivalent to
--   <tt><a>dropFinalBlank</a> . <a>keepDelimsR</a> .
--   <a>onSublist</a></tt>. For example:
--   
--   <pre>
--   split (endsWith "ly") "happilyslowlygnarlylily" == ["happily","slowly","gnarly","lily"]
--   </pre>
endsWith :: Eq a => [a] -> Splitter a

-- | Make a strategy that splits a list into chunks that all end with one
--   of the given elements, except possibly the last. Equivalent to
--   <tt><a>dropFinalBlank</a> . <a>keepDelimsR</a> . <a>oneOf</a></tt>.
--   For example:
--   
--   <pre>
--   split (condense $ endsWithOneOf ".,?! ") "Hi, there!  How are you?" == ["Hi, ","there!  ","How ","are ","you?"]
--   </pre>
endsWithOneOf :: Eq a => [a] -> Splitter a

-- | Split on any of the given elements. Equivalent to <tt><a>split</a> .
--   <a>dropDelims</a> . <a>oneOf</a></tt>. For example:
--   
--   <pre>
--   splitOneOf ";.," "foo,bar;baz.glurk" == ["foo","bar","baz","glurk"]
--   </pre>
splitOneOf :: Eq a => [a] -> [a] -> [[a]]

-- | Split on the given sublist. Equivalent to <tt><a>split</a> .
--   <a>dropDelims</a> . <a>onSublist</a></tt>. For example:
--   
--   <pre>
--   splitOn ".." "a..b...c....d.." == ["a","b",".c","","d",""]
--   </pre>
splitOn :: Eq a => [a] -> [a] -> [[a]]

-- | Split on elements satisfying the given predicate. Equivalent to
--   <tt><a>split</a> . <a>dropDelims</a> . <a>whenElt</a></tt>. For
--   example:
--   
--   <pre>
--   splitWhen (&lt;0) [1,3,-4,5,7,-9,0,2] == [[1,3],[5,7],[0,2]]
--   </pre>
splitWhen :: (a -> Bool) -> [a] -> [[a]]

-- | A synonym for <a>splitOn</a>.
sepBy :: Eq a => [a] -> [a] -> [[a]]

-- | A synonym for <a>splitOneOf</a>.
sepByOneOf :: Eq a => [a] -> [a] -> [[a]]

-- | Split into chunks terminated by the given subsequence. Equivalent to
--   <tt><a>split</a> . <a>dropFinalBlank</a> . <a>dropDelims</a> .
--   <a>onSublist</a></tt>. For example:
--   
--   <pre>
--   endBy ";" "foo;bar;baz;" == ["foo","bar","baz"]
--   </pre>
--   
--   Note also that the <a>lines</a> function from <a>Data.List</a> is
--   equivalent to <tt><a>endBy</a> "\n"</tt>.
endBy :: Eq a => [a] -> [a] -> [[a]]

-- | Split into chunks terminated by one of the given elements. Equivalent
--   to <tt><a>split</a> . <a>dropFinalBlank</a> . <a>dropDelims</a> .
--   <a>oneOf</a></tt>.
endByOneOf :: Eq a => [a] -> [a] -> [[a]]

-- | A synonym for <a>sepBy</a> / <a>splitOn</a>.
--   
--   Note that this is the right inverse of the <tt>intercalate</tt>
--   function from <a>Data.List</a>, that is, <tt><tt>intercalate</tt> x .
--   <a>unintercalate</a> x == <a>id</a></tt>. It is also the case that
--   <tt><a>unintercalate</a> x . <tt>intercalate</tt> x</tt> is
--   idempotent. <tt><a>unintercalate</a> x . <tt>intercalate</tt> x</tt>
--   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 <tt>x</tt> does not occur in any elements of the
--   input list. Working out why is left as an exercise for the reader.)
unintercalate :: Eq a => [a] -> [a] -> [[a]]

-- | Split into words, with word boundaries indicated by the given
--   predicate. Satisfies <tt>words === wordsBy isSpace</tt>; equivalent to
--   <tt>split . dropBlanks . dropDelims . whenElt</tt>. For example:
--   
--   <pre>
--   wordsBy (=='x') "dogxxxcatxbirdxx" == ["dog","cat","bird"]
--   </pre>
wordsBy :: (a -> Bool) -> [a] -> [[a]]

-- | Split into lines, with line boundaries indicated by the given
--   predicate. Satisfies <tt>lines === linesBy (=='\n')</tt>; equivalent
--   to <tt>split . dropFinalBlank . dropDelims . whenElt</tt>. For
--   example:
--   
--   <pre>
--   linesBy (=='x') "dogxxxcatxbirdxx" == ["dog","","","cat","bird",""]
--   </pre>
linesBy :: (a -> Bool) -> [a] -> [[a]]

-- | <tt><a>splitEvery</a> n</tt> splits a list into length-n pieces. The
--   last piece will be shorter if <tt>n</tt> does not evenly divide the
--   length of the list. If <tt>n &lt;= 0</tt>, <tt><a>splitEvery</a> n
--   l</tt> returns an infinite list of empty lists.
--   
--   Note that <tt><a>splitEvery</a> n []</tt> is <tt>[]</tt>, not
--   <tt>[[]]</tt>. This is intentional, and is consistent with a recursive
--   definition of <a>splitEvery</a>; it satisfies the property that
--   
--   <pre>
--   splitEvery n xs ++ splitEvery n ys == splitEvery n (xs ++ ys)
--   </pre>
--   
--   whenever <tt>n</tt> evenly divides the length of <tt>xs</tt>.
splitEvery :: Int -> [e] -> [[e]]

-- | A common synonym for <a>splitEvery</a>.
chunk :: Int -> [e] -> [[e]]

-- | Split a list into chunks of the given lengths. For example:
--   
--   <pre>
--   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]]
--   </pre>
--   
--   The behavior of <tt><a>splitPlaces</a> ls xs</tt> when <tt><a>sum</a>
--   ls /= <a>length</a> xs</tt> can be inferred from the above examples
--   and the fact that <a>splitPlaces</a> is total.
splitPlaces :: Integral a => [a] -> [e] -> [[e]]

-- | Split a list into chunks of the given lengths. Unlike
--   <a>splitPlaces</a>, the output list will always be the same length as
--   the first input argument. For example:
--   
--   <pre>
--   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],[]]
--   </pre>
splitPlacesBlanks :: Integral a => [a] -> [e] -> [[e]]

-- | A useful recursion pattern for processing a list to produce a new
--   list, often used for "chopping" up the input list. Typically chop is
--   called with some function that will consume an initial prefix of the
--   list and produce a value and the rest of the list.
--   
--   For example, many common Prelude functions can be implemented in terms
--   of <tt>chop</tt>:
--   
--   <pre>
--   group :: (Eq a) =&gt; [a] -&gt; [[a]]
--   group = chop (\ xs@(x:_) -&gt; span (==x) xs)
--   
--   words :: String -&gt; [String]
--   words = filter (not . null) . chop (span (not . isSpace) . dropWhile isSpace)
--   </pre>
chop :: ([a] -> (b, [a])) -> [a] -> [b]
instance Eq DelimPolicy
instance Show DelimPolicy
instance Eq CondensePolicy
instance Show CondensePolicy
instance Eq EndPolicy
instance Show EndPolicy
instance Show a => Show (Chunk a)
instance Eq a => Eq (Chunk a)


-- | The <a>Data.List.Split</a> module contains a wide range of strategies
--   for splitting lists with respect to some sort of delimiter, mostly
--   implemented through a unified combinator interface. The goal is to be
--   flexible yet simple. Scroll past the Synopsis for usage, examples, and
--   detailed documentation of all exported functions. If you want to learn
--   about the implementation, see <a>Data.List.Split.Internals</a>.
--   
--   A darcs repository containing the source (including a module with over
--   40 QuickCheck properties) can be found at
--   <a>http://code.haskell.org/~byorgey/code/split</a>.
module Data.List.Split

-- | Split on the given sublist. Equivalent to <tt><a>split</a> .
--   <a>dropDelims</a> . <a>onSublist</a></tt>. For example:
--   
--   <pre>
--   splitOn ".." "a..b...c....d.." == ["a","b",".c","","d",""]
--   </pre>
splitOn :: Eq a => [a] -> [a] -> [[a]]

-- | Split on any of the given elements. Equivalent to <tt><a>split</a> .
--   <a>dropDelims</a> . <a>oneOf</a></tt>. For example:
--   
--   <pre>
--   splitOneOf ";.," "foo,bar;baz.glurk" == ["foo","bar","baz","glurk"]
--   </pre>
splitOneOf :: Eq a => [a] -> [a] -> [[a]]

-- | Split on elements satisfying the given predicate. Equivalent to
--   <tt><a>split</a> . <a>dropDelims</a> . <a>whenElt</a></tt>. For
--   example:
--   
--   <pre>
--   splitWhen (&lt;0) [1,3,-4,5,7,-9,0,2] == [[1,3],[5,7],[0,2]]
--   </pre>
splitWhen :: (a -> Bool) -> [a] -> [[a]]

-- | A synonym for <a>splitOn</a>.
sepBy :: Eq a => [a] -> [a] -> [[a]]

-- | A synonym for <a>splitOneOf</a>.
sepByOneOf :: Eq a => [a] -> [a] -> [[a]]

-- | Split into chunks terminated by the given subsequence. Equivalent to
--   <tt><a>split</a> . <a>dropFinalBlank</a> . <a>dropDelims</a> .
--   <a>onSublist</a></tt>. For example:
--   
--   <pre>
--   endBy ";" "foo;bar;baz;" == ["foo","bar","baz"]
--   </pre>
--   
--   Note also that the <a>lines</a> function from <a>Data.List</a> is
--   equivalent to <tt><a>endBy</a> "\n"</tt>.
endBy :: Eq a => [a] -> [a] -> [[a]]

-- | Split into chunks terminated by one of the given elements. Equivalent
--   to <tt><a>split</a> . <a>dropFinalBlank</a> . <a>dropDelims</a> .
--   <a>oneOf</a></tt>.
endByOneOf :: Eq a => [a] -> [a] -> [[a]]

-- | A synonym for <a>sepBy</a> / <a>splitOn</a>.
--   
--   Note that this is the right inverse of the <tt>intercalate</tt>
--   function from <a>Data.List</a>, that is, <tt><tt>intercalate</tt> x .
--   <a>unintercalate</a> x == <a>id</a></tt>. It is also the case that
--   <tt><a>unintercalate</a> x . <tt>intercalate</tt> x</tt> is
--   idempotent. <tt><a>unintercalate</a> x . <tt>intercalate</tt> x</tt>
--   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 <tt>x</tt> does not occur in any elements of the
--   input list. Working out why is left as an exercise for the reader.)
unintercalate :: Eq a => [a] -> [a] -> [[a]]

-- | Split into words, with word boundaries indicated by the given
--   predicate. Satisfies <tt>words === wordsBy isSpace</tt>; equivalent to
--   <tt>split . dropBlanks . dropDelims . whenElt</tt>. For example:
--   
--   <pre>
--   wordsBy (=='x') "dogxxxcatxbirdxx" == ["dog","cat","bird"]
--   </pre>
wordsBy :: (a -> Bool) -> [a] -> [[a]]

-- | Split into lines, with line boundaries indicated by the given
--   predicate. Satisfies <tt>lines === linesBy (=='\n')</tt>; equivalent
--   to <tt>split . dropFinalBlank . dropDelims . whenElt</tt>. For
--   example:
--   
--   <pre>
--   linesBy (=='x') "dogxxxcatxbirdxx" == ["dog","","","cat","bird",""]
--   </pre>
linesBy :: (a -> Bool) -> [a] -> [[a]]

-- | <tt><a>splitEvery</a> n</tt> splits a list into length-n pieces. The
--   last piece will be shorter if <tt>n</tt> does not evenly divide the
--   length of the list. If <tt>n &lt;= 0</tt>, <tt><a>splitEvery</a> n
--   l</tt> returns an infinite list of empty lists.
--   
--   Note that <tt><a>splitEvery</a> n []</tt> is <tt>[]</tt>, not
--   <tt>[[]]</tt>. This is intentional, and is consistent with a recursive
--   definition of <a>splitEvery</a>; it satisfies the property that
--   
--   <pre>
--   splitEvery n xs ++ splitEvery n ys == splitEvery n (xs ++ ys)
--   </pre>
--   
--   whenever <tt>n</tt> evenly divides the length of <tt>xs</tt>.
splitEvery :: Int -> [e] -> [[e]]

-- | A common synonym for <a>splitEvery</a>.
chunk :: Int -> [e] -> [[e]]

-- | Split a list into chunks of the given lengths. For example:
--   
--   <pre>
--   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]]
--   </pre>
--   
--   The behavior of <tt><a>splitPlaces</a> ls xs</tt> when <tt><a>sum</a>
--   ls /= <a>length</a> xs</tt> can be inferred from the above examples
--   and the fact that <a>splitPlaces</a> is total.
splitPlaces :: Integral a => [a] -> [e] -> [[e]]

-- | Split a list into chunks of the given lengths. Unlike
--   <a>splitPlaces</a>, the output list will always be the same length as
--   the first input argument. For example:
--   
--   <pre>
--   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],[]]
--   </pre>
splitPlacesBlanks :: Integral a => [a] -> [e] -> [[e]]

-- | A useful recursion pattern for processing a list to produce a new
--   list, often used for "chopping" up the input list. Typically chop is
--   called with some function that will consume an initial prefix of the
--   list and produce a value and the rest of the list.
--   
--   For example, many common Prelude functions can be implemented in terms
--   of <tt>chop</tt>:
--   
--   <pre>
--   group :: (Eq a) =&gt; [a] -&gt; [[a]]
--   group = chop (\ xs@(x:_) -&gt; span (==x) xs)
--   
--   words :: String -&gt; [String]
--   words = filter (not . null) . chop (span (not . isSpace) . dropWhile isSpace)
--   </pre>
chop :: ([a] -> (b, [a])) -> [a] -> [b]

-- | A splitting strategy.
data Splitter a

-- | The default splitting strategy: keep delimiters in the output as
--   separate chunks, don't condense multiple consecutive delimiters into
--   one, keep initial and final blank chunks. Default delimiter is the
--   constantly false predicate.
--   
--   Note that <a>defaultSplitter</a> should normally not be used; use
--   <a>oneOf</a>, <a>onSublist</a>, or <a>whenElt</a> instead, which are
--   the same as the <a>defaultSplitter</a> with just the delimiter
--   overridden.
--   
--   The <a>defaultSplitter</a> strategy with any delimiter gives a
--   maximally information-preserving splitting strategy, in the sense that
--   (a) taking the <a>concat</a> of the output yields the original list,
--   and (b) given only the output list, we can reconstruct a
--   <a>Splitter</a> which would produce the same output list again given
--   the original input list. This default strategy can be overridden to
--   allow discarding various sorts of information.
defaultSplitter :: Splitter a

-- | Split a list according to the given splitting strategy. This is how to
--   "run" a <a>Splitter</a> that has been built using the other
--   combinators.
split :: Splitter a -> [a] -> [[a]]

-- | A splitting strategy that splits on any one of the given elements. For
--   example:
--   
--   <pre>
--   split (oneOf "xyz") "aazbxyzcxd" == ["aa","z","b","x","","y","","z","c","x","d"]
--   </pre>
oneOf :: Eq a => [a] -> Splitter a

-- | A splitting strategy that splits on the given list, when it is
--   encountered as an exact subsequence. For example:
--   
--   <pre>
--   split (onSublist "xyz") "aazbxyzcxd" == ["aazb","xyz","cxd"]
--   </pre>
--   
--   Note that splitting on the empty list is a special case, which splits
--   just before every element of the list being split. For example:
--   
--   <pre>
--   split (onSublist "") "abc" == ["","","a","","b","","c"]
--   split (dropDelims . dropBlanks $ onSublist "") "abc" == ["a","b","c"]
--   </pre>
--   
--   However, if you want to break a list into singleton elements like
--   this, you are better off using <tt><a>splitEvery</a> 1</tt>, or better
--   yet, <tt><a>map</a> (:[])</tt>.
onSublist :: Eq a => [a] -> Splitter a

-- | A splitting strategy that splits on any elements that satisfy the
--   given predicate. For example:
--   
--   <pre>
--   split (whenElt (&lt;0)) [2,4,-3,6,-9,1] == [[2,4],[-3],[6],[-9],[1]]
--   </pre>
whenElt :: (a -> Bool) -> Splitter a

-- | Drop delimiters from the output (the default is to keep them). For
--   example,
--   
--   <pre>
--   split (oneOf ":") "a:b:c" == ["a", ":", "b", ":", "c"]
--   split (dropDelims $ oneOf ":") "a:b:c" == ["a", "b", "c"]
--   </pre>
dropDelims :: Splitter a -> Splitter a

-- | Keep delimiters in the output by prepending them to adjacent chunks.
--   For example:
--   
--   <pre>
--   split (keepDelimsL $ oneOf "xyz") "aazbxyzcxd" == ["aa","zb","x","y","zc","xd"]
--   </pre>
keepDelimsL :: Splitter a -> Splitter a

-- | Keep delimiters in the output by appending them to adjacent chunks.
--   For example:
--   
--   <pre>
--   split (keepDelimsR $ oneOf "xyz") "aazbxyzcxd" == ["aaz","bx","y","z","cx","d"]
--   </pre>
keepDelimsR :: Splitter a -> Splitter a

-- | Condense multiple consecutive delimiters into one. For example:
--   
--   <pre>
--   split (condense $ oneOf "xyz") "aazbxyzcxd" == ["aa","z","b","xyz","c","x","d"]
--   split (dropDelims $ oneOf "xyz") "aazbxyzcxd" == ["aa","b","","","c","d"]
--   split (condense . dropDelims $ oneOf "xyz") "aazbxyzcxd" == ["aa","b","c","d"]
--   </pre>
condense :: Splitter a -> Splitter a

-- | Don't generate a blank chunk if there is a delimiter at the beginning.
--   For example:
--   
--   <pre>
--   split (oneOf ":") ":a:b" == ["",":","a",":","b"]
--   split (dropInitBlank $ oneOf ":") ":a:b" == [":","a",":","b"]
--   </pre>
dropInitBlank :: Splitter a -> Splitter a

-- | Don't generate a blank chunk if there is a delimiter at the end. For
--   example:
--   
--   <pre>
--   split (oneOf ":") "a:b:" == ["a",":","b",":",""]
--   split (dropFinalBlank $ oneOf ":") "a:b:" == ["a",":","b",":"]
--   </pre>
dropFinalBlank :: Splitter a -> Splitter a

-- | Drop all blank chunks from the output. Equivalent to
--   <tt><a>dropInitBlank</a> . <a>dropFinalBlank</a> .
--   <a>condense</a></tt>. For example:
--   
--   <pre>
--   split (oneOf ":") "::b:::a" == ["",":","",":","b",":","",":","",":","a"]
--   split (dropBlanks $ oneOf ":") "::b:::a" == ["::","b",":::","a"]
--   </pre>
dropBlanks :: Splitter a -> Splitter a

-- | Make a strategy that splits a list into chunks that all start with the
--   given subsequence (except possibly the first). Equivalent to
--   <tt><a>dropInitBlank</a> . <a>keepDelimsL</a> . <a>onSublist</a></tt>.
--   For example:
--   
--   <pre>
--   split (startsWith "app") "applyapplicativeapplaudapproachapple" == ["apply","applicative","applaud","approach","apple"]
--   </pre>
startsWith :: Eq a => [a] -> Splitter a

-- | Make a strategy that splits a list into chunks that all start with one
--   of the given elements (except possibly the first). Equivalent to
--   <tt><a>dropInitBlank</a> . <a>keepDelimsL</a> . <a>oneOf</a></tt>. For
--   example:
--   
--   <pre>
--   split (startsWithOneOf ['A'..'Z']) "ACamelCaseIdentifier" == ["A","Camel","Case","Identifier"]
--   </pre>
startsWithOneOf :: Eq a => [a] -> Splitter a

-- | Make a strategy that splits a list into chunks that all end with the
--   given subsequence, except possibly the last. Equivalent to
--   <tt><a>dropFinalBlank</a> . <a>keepDelimsR</a> .
--   <a>onSublist</a></tt>. For example:
--   
--   <pre>
--   split (endsWith "ly") "happilyslowlygnarlylily" == ["happily","slowly","gnarly","lily"]
--   </pre>
endsWith :: Eq a => [a] -> Splitter a

-- | Make a strategy that splits a list into chunks that all end with one
--   of the given elements, except possibly the last. Equivalent to
--   <tt><a>dropFinalBlank</a> . <a>keepDelimsR</a> . <a>oneOf</a></tt>.
--   For example:
--   
--   <pre>
--   split (condense $ endsWithOneOf ".,?! ") "Hi, there!  How are you?" == ["Hi, ","there!  ","How ","are ","you?"]
--   </pre>
endsWithOneOf :: Eq a => [a] -> Splitter a
