{-|

Module      : SplitList
Description : Examples with zipwith
Copyright   : © Frank Jung, 2020
License     : GPL-3

Split a list in half using 'zipWith'.

From
<https://github.com/quchen/articles/blob/master/2018-11-22_zipWith_const.md My favorite Haskell function by David Luposchainsky>

-}

module SplitList (every2nd, zipOverflow, splitMiddle) where

-- | Split list into two.
splitMiddle :: [a] -> ([a], [a])
splitMiddle :: forall a. [a] -> ([a], [a])
splitMiddle [a]
xs = let firstHalf :: [a]
firstHalf = (a -> a -> a) -> [a] -> [a] -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> a -> a
forall a b. a -> b -> a
const [a]
xs ([a] -> [a]
forall a. [a] -> [a]
every2nd [a]
xs)
                     secondHalf :: [a]
secondHalf = [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
zipOverflow [a]
firstHalf [a]
xs
                 in ([a]
firstHalf, [a]
secondHalf)

-- | Drop every second element.
every2nd :: [a] -> [a]
every2nd :: forall a. [a] -> [a]
every2nd (a
x:a
_:[a]
xs) = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
forall a. [a] -> [a]
every2nd [a]
xs
every2nd [a]
_        = []

-- | Ignore count of first elements then print overflow from second.
zipOverflow :: [a] -> [a] -> [a]
zipOverflow :: forall a. [a] -> [a] -> [a]
zipOverflow (a
_:[a]
xs) (a
_:[a]
ys) = [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
zipOverflow [a]
xs [a]
ys
zipOverflow [] [a]
ys         = [a]
ys -- end of first list so return rest of second
zipOverflow [a]
xs []         = [a]
xs -- end of second list so return rest of first