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

-- | Combinator library for splitting lists.
--   
--   A collection of various methods for splitting lists into parts, akin
--   to the "split" function found in several mainstream languages. Here is
--   its tale:
--   
--   Once upon a time the standard Data.List module held no function
--   for splitting a list into parts according to a delimiter. Many a brave
--   lambda-knight strove to add such a function, but their striving was in
--   vain, for Lo, the Supreme Council fell to bickering amongst themselves
--   what was to be the essential nature of the One True Function which
--   could cleave a list in twain (or thrain, or any required number of
--   parts).
--   
--   And thus came to pass the split package, comprising divers functions
--   for splitting a list asunder, each according to its nature. And the
--   Supreme Council had no longer any grounds for argument, for the
--   favored method of each was contained therein.
--   
--   To get started, see the Data.List.Split module.
@package split
@version 0.2.5

-- | Implementation module for Data.List.Split, a combinator library
--   for splitting lists. See the Data.List.Split 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 defaultSplitter should normally not be used; use
--   oneOf, onSublist, or whenElt instead, which are
--   the same as the defaultSplitter with just the delimiter
--   overridden.
--   
--   The defaultSplitter strategy with any delimiter gives a
--   maximally information-preserving splitting strategy, in the sense that
--   (a) taking the concat of the output yields the original list,
--   and (b) given only the output list, we can reconstruct a
--   Splitter 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 is a list of predicates on elements, matched by some
--   contiguous subsequence of a list.
newtype Delimiter a
Delimiter :: [a -> Bool] -> 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

-- | Keep consecutive delimiters separate, but don't insert blank chunks in
--   between them.
DropBlankFields :: 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 Chunk.
fromElem :: Chunk a -> [a]

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

-- | Test whether a Chunk 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,
--   
--   
--   concatMap fromElem (splitInternal d l) == l.
--   
splitInternal :: Delimiter a -> [a] -> SplitList 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 Splitter.
postProcess :: Splitter a -> SplitList a -> SplitList a

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

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

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

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

-- | Merge delimiters into adjacent chunks according to the
--   DelimPolicy.
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 EndPolicy.
dropInitial :: EndPolicy -> SplitList a -> SplitList a

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

-- | Split a list according to the given splitting strategy. This is how to
--   "run" a Splitter 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.
--   
--   
--   >>> split (oneOf ",;") "hi;there,world"
--   ["hi",";","there",",","world"]
--   
--   
--   
--   >>> split (oneOf "xyz") "aazbxyzcxd"
--   ["aa","z","b","x","","y","","z","c","x","d"]
--   
oneOf :: Eq a => [a] -> Splitter a

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

-- | A splitting strategy that splits on any elements that satisfy the
--   given predicate.
--   
--   
--   >>> split (whenElt (<0)) [2,4,-3,6,-9,1 :: Int]
--   [[2,4],[-3],[6],[-9],[1]]
--   
whenElt :: (a -> Bool) -> Splitter a

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

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

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

-- | Condense multiple consecutive delimiters into one.
--   
--   
--   >>> 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"]
--   
condense :: Splitter a -> Splitter a

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

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

-- | Don't generate blank chunks between consecutive delimiters.
--   
--   
--   >>> split (oneOf ":") "::b:::a"
--   ["",":","",":","b",":","",":","",":","a"]
--   
--   
--   
--   >>> split (dropInnerBlanks $ oneOf ":") "::b:::a"
--   ["",":",":","b",":",":",":","a"]
--   
dropInnerBlanks :: Splitter a -> Splitter a

-- | Split over a different type of element by performing a preprocessing
--   step.
--   
--   
--   >>> split (mapSplitter snd $ oneOf "-_") $ zip [0..] "a-bc_d"
--   [[(0,'a')],[(1,'-')],[(2,'b'),(3,'c')],[(4,'_')],[(5,'d')]]
--   
--   
--   
--   >>> import Data.Char (toLower)
--   
--   >>> split (mapSplitter toLower $ dropDelims $ whenElt (== 'x')) "abXcxd"
--   ["ab","c","d"]
--   
mapSplitter :: (b -> a) -> Splitter a -> Splitter b

-- | Drop all blank chunks from the output, and condense consecutive
--   delimiters into one. Equivalent to dropInitBlank .
--   dropFinalBlank . condense.
--   
--   
--   >>> split (oneOf ":") "::b:::a"
--   ["",":","",":","b",":","",":","",":","a"]
--   
--   
--   
--   >>> split (dropBlanks $ oneOf ":") "::b:::a"
--   ["::","b",":::","a"]
--   
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
--   dropInitBlank . keepDelimsL . onSublist.
--   
--   
--   >>> split (startsWith "app") "applyapplicativeapplaudapproachapple"
--   ["apply","applicative","applaud","approach","apple"]
--   
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
--   dropInitBlank . keepDelimsL . oneOf.
--   example:
--   
--   
--   >>> split (startsWithOneOf ['A'..'Z']) "ACamelCaseIdentifier"
--   ["A","Camel","Case","Identifier"]
--   
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
--   dropFinalBlank . keepDelimsR .
--   onSublist.
--   
--   
--   >>> split (endsWith "ly") "happilyslowlygnarlylily"
--   ["happily","slowly","gnarly","lily"]
--   
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
--   dropFinalBlank . keepDelimsR . oneOf.
--   
--   
--   >>> split (condense $ endsWithOneOf ".,?! ") "Hi, there!  How are you?"
--   ["Hi, ","there!  ","How ","are ","you?"]
--   
endsWithOneOf :: Eq a => [a] -> Splitter a

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

-- | 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.)
splitOn :: Eq a => [a] -> [a] -> [[a]]

-- | Split on elements satisfying the given predicate. Equivalent to
--   split . dropDelims . whenElt.
--   
--   
--   >>> splitWhen (<0) [1,3,-4,5,7,-9,0,2]
--   [[1,3],[5,7],[0,2]]
--   
--   
--   
--   >>> splitWhen (<0) [1,-2,3,4,-5,-6,7,8,-9]
--   [[1],[3,4],[],[7,8],[]]
--   
splitWhen :: (a -> Bool) -> [a] -> [[a]]

-- | 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".
endBy :: Eq a => [a] -> [a] -> [[a]]

-- | Split into chunks terminated by one of the given elements. Equivalent
--   to split . dropFinalBlank . dropDelims .
--   oneOf.
--   
--   
--   >>> endByOneOf ";," "foo;bar,baz;"
--   ["foo","bar","baz"]
--   
endByOneOf :: Eq a => [a] -> [a] -> [[a]]

-- | Split into "words", with word boundaries indicated by the given
--   predicate. Satisfies words === wordsBy isSpace;
--   equivalent to split . dropBlanks . dropDelims
--   . whenElt.
--   
--   
--   >>> wordsBy (`elem` ",;.?! ") "Hello there, world! How?"
--   ["Hello","there","world","How"]
--   
--   
--   
--   >>> wordsBy (=='x') "dogxxxcatxbirdxx"
--   ["dog","cat","bird"]
--   
wordsBy :: (a -> Bool) -> [a] -> [[a]]

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

-- | Standard build function, specialized to building lists.
--   
--   Usually build is given the rank-2 type
--   
--   
--   build :: (forall b. (a -> b -> b) -> b -> b) -> [a]
--   
--   
--   but since we only use it when (b ~ [a]), we give it the more
--   restricted type signature in order to avoid needing a non-Haskell2010
--   extension.
--   
--   Note that the 0.1.4.3 release of this package did away with a custom
--   build implementation in favor of importing one from
--   GHC.Exts, which was (reportedly) faster for some applications.
--   However, in the interest of simplicity and complete Haskell2010
--   compliance as split is being included in the Haskel Platform,
--   version 0.2.1.0 has gone back to defining build manually.
--   This is in line with split's design philosophy of having
--   efficiency as a non-goal.
build :: ((a -> [a] -> [a]) -> [a] -> [a]) -> [a]

-- | chunksOf n splits a list into length-n pieces. The
--   last piece will be shorter if n does not evenly divide the
--   length of the list. If n <= 0, chunksOf n
--   l returns an infinite list of empty lists.
--   
--   
--   >>> chunksOf 3 [1..12]
--   [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
--   
--   
--   
--   >>> chunksOf 3 "Hello there"
--   ["Hel","lo ","the","re"]
--   
--   
--   
--   >>> chunksOf 3 ([] :: [Int])
--   []
--   
--   
--   Note that chunksOf n [] is [], not
--   [[]]. This is intentional, and satisfies the property that
--   
--   
--   chunksOf n xs ++ chunksOf n ys == chunksOf n (xs ++ ys)
--   
--   
--   whenever n evenly divides the length of xs.
chunksOf :: Int -> [e] -> [[e]]

-- | 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.
splitPlaces :: Integral a => [a] -> [e] -> [[e]]

-- | 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.
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 chop:
--   
--   
--   group :: (Eq a) => [a] -> [[a]]
--   group = chop (\ xs@(x:_) -> span (==x) xs)
--   
--   words :: String -> [String]
--   words = filter (not . null) . chop (break isSpace . dropWhile isSpace)
--   
chop :: ([a] -> (b, [a])) -> [a] -> [b]

-- | Divides up an input list into a set of sublists, according to
--   n and m input specifications you provide. Each
--   sublist will have n items, and the start of each sublist will
--   be offset by m items from the previous one.
--   
--   
--   >>> divvy 5 5 [1..15]
--   [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]]
--   
--   
--   
--   >>> divvy 5 2 [1..15]
--   [[1,2,3,4,5],[3,4,5,6,7],[5,6,7,8,9],[7,8,9,10,11],[9,10,11,12,13],[11,12,13,14,15]]
--   
--   
--   In the case where a source list's trailing elements do no fill an
--   entire sublist, those trailing elements will be dropped.
--   
--   
--   >>> divvy 5 2 [1..10]
--   [[1,2,3,4,5],[3,4,5,6,7],[5,6,7,8,9]]
--   
--   
--   As an example, you can generate a moving average over a list of
--   prices:
--   
--   
--   type Prices = [Float]
--   type AveragePrices = [Float]
--   
--   average :: [Float] -> Float
--   average xs = sum xs / (fromIntegral $ length xs)
--   
--   simpleMovingAverage :: Prices -> AveragePrices
--   simpleMovingAverage = map average . divvy 20 1
--   
divvy :: Int -> Int -> [a] -> [[a]]
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.List.Split.Internals.Chunk a)
instance GHC.Classes.Eq Data.List.Split.Internals.CondensePolicy
instance GHC.Classes.Eq Data.List.Split.Internals.DelimPolicy
instance GHC.Classes.Eq Data.List.Split.Internals.EndPolicy
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.List.Split.Internals.Chunk a)
instance GHC.Internal.Show.Show Data.List.Split.Internals.CondensePolicy
instance GHC.Internal.Show.Show Data.List.Split.Internals.DelimPolicy
instance GHC.Internal.Show.Show Data.List.Split.Internals.EndPolicy

-- | The Data.List.Split 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. See below for usage, examples, and detailed
--   documentation of all exported functions. If you want to learn about
--   the implementation, see Data.List.Split.Internals.
--   
--   A git repository containing the source (including a module with over
--   40 QuickCheck properties) can be found at
--   https://github.com/byorgey/split.
module Data.List.Split

-- | 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.)
splitOn :: Eq a => [a] -> [a] -> [[a]]

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

-- | Split on elements satisfying the given predicate. Equivalent to
--   split . dropDelims . whenElt.
--   
--   
--   >>> splitWhen (<0) [1,3,-4,5,7,-9,0,2]
--   [[1,3],[5,7],[0,2]]
--   
--   
--   
--   >>> splitWhen (<0) [1,-2,3,4,-5,-6,7,8,-9]
--   [[1],[3,4],[],[7,8],[]]
--   
splitWhen :: (a -> Bool) -> [a] -> [[a]]

-- | 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".
endBy :: Eq a => [a] -> [a] -> [[a]]

-- | Split into chunks terminated by one of the given elements. Equivalent
--   to split . dropFinalBlank . dropDelims .
--   oneOf.
--   
--   
--   >>> endByOneOf ";," "foo;bar,baz;"
--   ["foo","bar","baz"]
--   
endByOneOf :: Eq a => [a] -> [a] -> [[a]]

-- | Split into "words", with word boundaries indicated by the given
--   predicate. Satisfies words === wordsBy isSpace;
--   equivalent to split . dropBlanks . dropDelims
--   . whenElt.
--   
--   
--   >>> wordsBy (`elem` ",;.?! ") "Hello there, world! How?"
--   ["Hello","there","world","How"]
--   
--   
--   
--   >>> wordsBy (=='x') "dogxxxcatxbirdxx"
--   ["dog","cat","bird"]
--   
wordsBy :: (a -> Bool) -> [a] -> [[a]]

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

-- | chunksOf n splits a list into length-n pieces. The
--   last piece will be shorter if n does not evenly divide the
--   length of the list. If n <= 0, chunksOf n
--   l returns an infinite list of empty lists.
--   
--   
--   >>> chunksOf 3 [1..12]
--   [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
--   
--   
--   
--   >>> chunksOf 3 "Hello there"
--   ["Hel","lo ","the","re"]
--   
--   
--   
--   >>> chunksOf 3 ([] :: [Int])
--   []
--   
--   
--   Note that chunksOf n [] is [], not
--   [[]]. This is intentional, and satisfies the property that
--   
--   
--   chunksOf n xs ++ chunksOf n ys == chunksOf n (xs ++ ys)
--   
--   
--   whenever n evenly divides the length of xs.
chunksOf :: Int -> [e] -> [[e]]

-- | 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.
splitPlaces :: Integral a => [a] -> [e] -> [[e]]

-- | 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.
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 chop:
--   
--   
--   group :: (Eq a) => [a] -> [[a]]
--   group = chop (\ xs@(x:_) -> span (==x) xs)
--   
--   words :: String -> [String]
--   words = filter (not . null) . chop (break isSpace . dropWhile isSpace)
--   
chop :: ([a] -> (b, [a])) -> [a] -> [b]

-- | Divides up an input list into a set of sublists, according to
--   n and m input specifications you provide. Each
--   sublist will have n items, and the start of each sublist will
--   be offset by m items from the previous one.
--   
--   
--   >>> divvy 5 5 [1..15]
--   [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]]
--   
--   
--   
--   >>> divvy 5 2 [1..15]
--   [[1,2,3,4,5],[3,4,5,6,7],[5,6,7,8,9],[7,8,9,10,11],[9,10,11,12,13],[11,12,13,14,15]]
--   
--   
--   In the case where a source list's trailing elements do no fill an
--   entire sublist, those trailing elements will be dropped.
--   
--   
--   >>> divvy 5 2 [1..10]
--   [[1,2,3,4,5],[3,4,5,6,7],[5,6,7,8,9]]
--   
--   
--   As an example, you can generate a moving average over a list of
--   prices:
--   
--   
--   type Prices = [Float]
--   type AveragePrices = [Float]
--   
--   average :: [Float] -> Float
--   average xs = sum xs / (fromIntegral $ length xs)
--   
--   simpleMovingAverage :: Prices -> AveragePrices
--   simpleMovingAverage = map average . divvy 20 1
--   
divvy :: Int -> Int -> [a] -> [[a]]

-- | 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 defaultSplitter should normally not be used; use
--   oneOf, onSublist, or whenElt instead, which are
--   the same as the defaultSplitter with just the delimiter
--   overridden.
--   
--   The defaultSplitter strategy with any delimiter gives a
--   maximally information-preserving splitting strategy, in the sense that
--   (a) taking the concat of the output yields the original list,
--   and (b) given only the output list, we can reconstruct a
--   Splitter 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 Splitter 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.
--   
--   
--   >>> split (oneOf ",;") "hi;there,world"
--   ["hi",";","there",",","world"]
--   
--   
--   
--   >>> split (oneOf "xyz") "aazbxyzcxd"
--   ["aa","z","b","x","","y","","z","c","x","d"]
--   
oneOf :: Eq a => [a] -> Splitter a

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

-- | A splitting strategy that splits on any elements that satisfy the
--   given predicate.
--   
--   
--   >>> split (whenElt (<0)) [2,4,-3,6,-9,1 :: Int]
--   [[2,4],[-3],[6],[-9],[1]]
--   
whenElt :: (a -> Bool) -> Splitter a

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

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

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

-- | Condense multiple consecutive delimiters into one.
--   
--   
--   >>> 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"]
--   
condense :: Splitter a -> Splitter a

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

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

-- | Don't generate blank chunks between consecutive delimiters.
--   
--   
--   >>> split (oneOf ":") "::b:::a"
--   ["",":","",":","b",":","",":","",":","a"]
--   
--   
--   
--   >>> split (dropInnerBlanks $ oneOf ":") "::b:::a"
--   ["",":",":","b",":",":",":","a"]
--   
dropInnerBlanks :: Splitter a -> Splitter a

-- | Split over a different type of element by performing a preprocessing
--   step.
--   
--   
--   >>> split (mapSplitter snd $ oneOf "-_") $ zip [0..] "a-bc_d"
--   [[(0,'a')],[(1,'-')],[(2,'b'),(3,'c')],[(4,'_')],[(5,'d')]]
--   
--   
--   
--   >>> import Data.Char (toLower)
--   
--   >>> split (mapSplitter toLower $ dropDelims $ whenElt (== 'x')) "abXcxd"
--   ["ab","c","d"]
--   
mapSplitter :: (b -> a) -> Splitter a -> Splitter b

-- | Drop all blank chunks from the output, and condense consecutive
--   delimiters into one. Equivalent to dropInitBlank .
--   dropFinalBlank . condense.
--   
--   
--   >>> split (oneOf ":") "::b:::a"
--   ["",":","",":","b",":","",":","",":","a"]
--   
--   
--   
--   >>> split (dropBlanks $ oneOf ":") "::b:::a"
--   ["::","b",":::","a"]
--   
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
--   dropInitBlank . keepDelimsL . onSublist.
--   
--   
--   >>> split (startsWith "app") "applyapplicativeapplaudapproachapple"
--   ["apply","applicative","applaud","approach","apple"]
--   
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
--   dropInitBlank . keepDelimsL . oneOf.
--   example:
--   
--   
--   >>> split (startsWithOneOf ['A'..'Z']) "ACamelCaseIdentifier"
--   ["A","Camel","Case","Identifier"]
--   
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
--   dropFinalBlank . keepDelimsR .
--   onSublist.
--   
--   
--   >>> split (endsWith "ly") "happilyslowlygnarlylily"
--   ["happily","slowly","gnarly","lily"]
--   
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
--   dropFinalBlank . keepDelimsR . oneOf.
--   
--   
--   >>> split (condense $ endsWithOneOf ".,?! ") "Hi, there!  How are you?"
--   ["Hi, ","there!  ","How ","are ","you?"]
--   
endsWithOneOf :: Eq a => [a] -> Splitter a
