packages feed

polyglot-0.1.1.0: src/Utils/List.hs

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 = (Nel.head <$>) . Nel.nonEmpty

safeLast :: [a] -> Maybe a
safeLast = (Nel.last <$>) . Nel.nonEmpty

safeTail :: [a] -> Maybe [a]
safeTail = (Nel.tail <$>) . Nel.nonEmpty

safeInit :: [a] -> Maybe [a]
safeInit = (Nel.init <$>) . Nel.nonEmpty


groupByKey :: Eq b => (a -> b) -> [a] -> [[a]]
groupByKey f x = groupBy (\a b -> f a == f b) x


groupTuplesByKey :: Eq a => [(a, b)] -> [(a, [b])]
groupTuplesByKey x = (\a -> (fst $ head a, snd <$> a)) <$>
                        groupByKey fst x


sortByKey :: Ord b => (a -> b) -> [a] -> [a]
sortByKey f x = sortBy (\a b -> f a `compare` f b) x


zipWithKey :: Eq a => [(a, b)] ->  [(a, c)] -> [(b, Maybe c)]
zipWithKey x y = (\a ->  (snd a, snd <$> (find (\b -> fst a == fst b) y))) <$> x


mergeUnion :: Eq a => [(a, b)] -> [(a, c)] -> [(Maybe b, Maybe c)]
mergeUnion x y =  a ++ b
  where
    a = (first Just) <$> zipWithKey x y
    b = (tupleReverse . (first Just)) <$> zipWithKey y x


mix :: [a] -> [a] -> [a]
mix (x : xs) (y : ys) = x : y : mix xs ys
mix [] ys             = ys
mix xs []             = xs


tupleReverse :: (b, a) -> (a, b)
tupleReverse (x, y) = (y, x)