module Language.Haskell.Formatter.Toolkit.ListTool
(maybeLast, dropWhileAtMost, mergeLongerSuccessions, takeEvery,
concatenateRuns, concatenateShiftedRuns)
where
import qualified Data.List as List
import qualified Data.Maybe as Maybe
import qualified Data.Monoid as Monoid
maybeLast :: [a] -> Maybe a
maybeLast = Maybe.listToMaybe . reverse
dropWhileAtMost :: (a -> Bool) -> Int -> [a] -> [a]
dropWhileAtMost predicate limit list
= Monoid.mappend (dropWhile predicate deformable) rigid
where (deformable, rigid) = splitAt limit list
mergeLongerSuccessions :: (a -> Bool) -> Int -> [a] -> [a]
mergeLongerSuccessions predicate count = snd . List.foldl' merge (0, [])
where merge (successionLength, list) element
= if predicate element then
if successionLength < count then (succ successionLength, extended)
else (count, list)
else (0, extended)
where extended = Monoid.mappend list [element]
takeEvery :: Int -> [a] -> [a]
takeEvery _ [] = []
takeEvery period list@(first : _) = first : takeEvery period (drop period list)
concatenateRuns :: Int -> [[a]] -> [[a]]
concatenateRuns _ [] = []
concatenateRuns period lists = concat run : concatenateRuns period rest
where (run, rest) = splitAt period lists
concatenateShiftedRuns :: Int -> Int -> [[a]] -> [[a]]
concatenateShiftedRuns period shift lists
= case shift of
0 -> concatenateUnshifted lists
_ -> concat shifted : concatenateUnshifted unshifted
where (shifted, unshifted) = splitAt shift lists
where concatenateUnshifted = concatenateRuns period