module Utils.List where import qualified Data.List.NonEmpty as Nel import Data.Foldable (find) import Data.List (groupBy, sortBy) import Data.Tuple.Extra (first) safeHead :: [a] -> Maybe a safeHead :: forall a. [a] -> Maybe a safeHead = (forall a. NonEmpty a -> a Nel.head <$>) forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. [a] -> Maybe (NonEmpty a) Nel.nonEmpty safeLast :: [a] -> Maybe a safeLast :: forall a. [a] -> Maybe a safeLast = (forall a. NonEmpty a -> a Nel.last <$>) forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. [a] -> Maybe (NonEmpty a) Nel.nonEmpty safeTail :: [a] -> Maybe [a] safeTail :: forall a. [a] -> Maybe [a] safeTail = (forall a. NonEmpty a -> [a] Nel.tail <$>) forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. [a] -> Maybe (NonEmpty a) Nel.nonEmpty safeInit :: [a] -> Maybe [a] safeInit :: forall a. [a] -> Maybe [a] safeInit = (forall a. NonEmpty a -> [a] Nel.init <$>) forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. [a] -> Maybe (NonEmpty a) Nel.nonEmpty groupByKey :: Eq b => (a -> b) -> [a] -> [[a]] groupByKey :: forall b a. Eq b => (a -> b) -> [a] -> [[a]] groupByKey a -> b f [a] x = forall a. (a -> a -> Bool) -> [a] -> [[a]] groupBy (\a a a b -> a -> b f a a forall a. Eq a => a -> a -> Bool == a -> b f a b) [a] x groupTuplesByKey :: Eq a => [(a, b)] -> [(a, [b])] groupTuplesByKey :: forall a b. Eq a => [(a, b)] -> [(a, [b])] groupTuplesByKey [(a, b)] x = (\[(a, b)] a -> (forall a b. (a, b) -> a fst forall a b. (a -> b) -> a -> b $ forall a. [a] -> a head [(a, b)] a, forall a b. (a, b) -> b snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [(a, b)] a)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall b a. Eq b => (a -> b) -> [a] -> [[a]] groupByKey forall a b. (a, b) -> a fst [(a, b)] x sortByKey :: Ord b => (a -> b) -> [a] -> [a] sortByKey :: forall b a. Ord b => (a -> b) -> [a] -> [a] sortByKey a -> b f [a] x = forall a. (a -> a -> Ordering) -> [a] -> [a] sortBy (\a a a b -> a -> b f a a forall a. Ord a => a -> a -> Ordering `compare` a -> b f a b) [a] x zipWithKey :: Eq a => [(a, b)] -> [(a, c)] -> [(b, Maybe c)] zipWithKey :: forall a b c. Eq a => [(a, b)] -> [(a, c)] -> [(b, Maybe c)] zipWithKey [(a, b)] x [(a, c)] y = (\(a, b) a -> (forall a b. (a, b) -> b snd (a, b) a, forall a b. (a, b) -> b snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a find (\(a, c) b -> forall a b. (a, b) -> a fst (a, b) a forall a. Eq a => a -> a -> Bool == forall a b. (a, b) -> a fst (a, c) b) [(a, c)] y))) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [(a, b)] x mergeUnion :: Eq a => [(a, b)] -> [(a, c)] -> [(Maybe b, Maybe c)] mergeUnion :: forall a b c. Eq a => [(a, b)] -> [(a, c)] -> [(Maybe b, Maybe c)] mergeUnion [(a, b)] x [(a, c)] y = [(Maybe b, Maybe c)] a forall a. [a] -> [a] -> [a] ++ [(Maybe b, Maybe c)] b where a :: [(Maybe b, Maybe c)] a = (forall a a' b. (a -> a') -> (a, b) -> (a', b) first forall a. a -> Maybe a Just) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall a b c. Eq a => [(a, b)] -> [(a, c)] -> [(b, Maybe c)] zipWithKey [(a, b)] x [(a, c)] y b :: [(Maybe b, Maybe c)] b = (forall b a. (b, a) -> (a, b) tupleReverse forall b c a. (b -> c) -> (a -> b) -> a -> c . (forall a a' b. (a -> a') -> (a, b) -> (a', b) first forall a. a -> Maybe a Just)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall a b c. Eq a => [(a, b)] -> [(a, c)] -> [(b, Maybe c)] zipWithKey [(a, c)] y [(a, b)] x mix :: [a] -> [a] -> [a] mix :: forall a. [a] -> [a] -> [a] mix (a x : [a] xs) (a y : [a] ys) = a x forall a. a -> [a] -> [a] : a y forall a. a -> [a] -> [a] : forall a. [a] -> [a] -> [a] mix [a] xs [a] ys mix [] [a] ys = [a] ys mix [a] xs [] = [a] xs tupleReverse :: (b, a) -> (a, b) tupleReverse :: forall b a. (b, a) -> (a, b) tupleReverse (b x, a y) = (a y, b x)