content: 
  -- | Replacements for unhelpful Haskell list functions.
  --   If the standard versions are passed an empty list then we don't
  --   get a proper source location.
  module DDC.Data.ListUtils
          ( takeHead
          , takeTail
          , takeInit
          , takeMaximum
          , index
          , findDuplicates
          , stripSuffix)
  where
  import Data.List
  import qualified Data.Set as Set
  
  
  -- | Take the head of a list, or `Nothing` if it's empty.
  takeHead :: [a] -> Maybe a
  takeHead xs
   = case xs of
          []      -> Nothing
          _       -> Just (head xs)
  
  
  -- | Take the tail of a list, or `Nothing` if it's empty.
  takeTail :: [a] -> Maybe [a]
  takeTail xs
   = case xs of
          []      -> Nothing
          _       -> Just (tail xs)
  
  
  -- | Take the init of a list, or `Nothing` if it's empty.
  takeInit :: [a] -> Maybe [a]
  takeInit xs
   = case xs of
          []      -> Nothing
          _       -> Just (init xs)
  
  
  -- | Take the maximum of a list, or `Nothing` if it's empty.
  takeMaximum :: Ord a => [a] -> Maybe a
  takeMaximum xs
   = case xs of
          []      -> Nothing
          _       -> Just (maximum xs)
  
  
  -- | Retrieve the element at the given index,
  --   or `Nothing if it's not there.
  index :: [a] -> Int -> Maybe a
  index [] _              = Nothing
  index (x : _)  0        = Just x
  index (_ : xs) i        = index xs (i - 1)
  
  
  
  -- | Find the duplicate values in a list.
  findDuplicates :: Ord n => [n] -> [n]
  findDuplicates xx
   = go (Set.fromList xx) xx
   where  go _  []            = []
          go ss (x : xs)
           | Set.member x ss  =     go (Set.delete x ss) xs
           | otherwise        = x : go ss xs
  
  
  -- | Drops the given suffix from a list.
  stripSuffix :: Eq a => [a] -> [a] -> Maybe [a]
  stripSuffix suff xx
   = case stripPrefix (reverse suff) (reverse xx) of
          Nothing -> Nothing
          Just xs -> Just $ reverse xs
  
  