-- | Utility functions to work with pairs of lists, which may be non-empty.
module Data.Text.ParagraphLayout.Internal.SplitList
( allowFstEmpty
, allowSndEmpty
, nonEmptyPairs
, nonEmptyFsts
, nonEmptySnds
)
where
import Data.List.NonEmpty (NonEmpty, nonEmpty, toList)
import Data.Maybe (catMaybes)
-- | Generalise the first component of a pair from a non-empty list
-- to a regular list.
allowFstEmpty :: (NonEmpty a, b) -> ([a], b)
allowFstEmpty (a, b) = (toList a, b)
-- | Generalise the second component of a pair from a non-empty list
-- to a regular list.
allowSndEmpty :: (a, NonEmpty b) -> (a, [b])
allowSndEmpty (a, b) = (a, toList b)
-- | Turn pairs of normal lists into pairs of `NonEmpty` lists,
-- removing pairs in which either list is empty.
nonEmptyPairs :: [([a], [b])] -> [(NonEmpty a, NonEmpty b)]
nonEmptyPairs = catMaybes . map nonEmptyPair
-- | Turn a pair of normal lists into `Just` a pair of `NonEmpty` lists,
-- or `Nothing` if either list is empty.
nonEmptyPair :: ([a], [b]) -> Maybe (NonEmpty a, NonEmpty b)
nonEmptyPair (xs, ys) = case (nonEmpty xs, nonEmpty ys) of
(Just xs1, Just ys1) -> Just (xs1, ys1)
(_, _) -> Nothing
-- | Turn pairs of normal lists into pairs where the first list is `NonEmpty`,
-- removing pairs in which the first list is empty.
nonEmptyFsts :: [([a], [b])] -> [(NonEmpty a, [b])]
nonEmptyFsts = catMaybes . map nonEmptyFst
-- | Turn a pair of normal lists into `Just` a pair where the first list is
-- `NonEmpty`, or `Nothing` if the first list is empty.
nonEmptyFst :: ([a], [b]) -> Maybe (NonEmpty a, [b])
nonEmptyFst (xs, ys) = case nonEmpty xs of
Just xs1 -> Just (xs1, ys)
Nothing -> Nothing
-- | Turn pairs of normal lists into pairs where the second list is `NonEmpty`,
-- removing pairs in which the second list is empty.
nonEmptySnds :: [([a], [b])] -> [([a], NonEmpty b)]
nonEmptySnds = catMaybes . map nonEmptySnd
-- | Turn a pair of normal lists into `Just` a pair where the second list is
-- `NonEmpty`, or `Nothing` if the second list is empty.
nonEmptySnd :: ([a], [b]) -> Maybe ([a], NonEmpty b)
nonEmptySnd (xs, ys) = case nonEmpty ys of
Just ys1 -> Just (xs, ys1)
Nothing -> Nothing