module Util
where
import Data.Set (Set)
import qualified Data.Set as Set
import qualified Data.Foldable as Foldable
import Data.Map (Map)
import qualified Data.Map as Map
import qualified Data.List as List

deleteAt :: Int -> [a] -> [a]
deleteAt i xs = ys ++ tail zs where
    (ys,zs) = splitAt i xs

maybeTuple :: Maybe (a,b) -> (Maybe a, Maybe b)
maybeTuple (Just (a,b)) = (Just a, Just b)
maybeTuple Nothing = (Nothing, Nothing)

compose :: [(a -> a)] -> (a -> a)
compose = foldr (.) id

graph :: (a -> b) -> a -> (a,b)
graph f x = (x, f x)

isNotASubsetOf :: Ord k => Set k -> Set k -> Bool
isNotASubsetOf s s' = not (Set.isSubsetOf s s')

getSubmap :: (Ord k, Foldable f) => Map k a -> f k -> Map k a
getSubmap theMap theKeys = Map.fromList $ graph (theMap Map.!) <$> List.nub (Foldable.toList theKeys)

deleteKeys :: (Ord k, Foldable f) => Map k a -> f k -> Map k a
deleteKeys theMap theKeys = compose (Map.delete <$> List.nub (Foldable.toList theKeys)) theMap

cartesian :: [a] -> [b] -> [(a,b)]
cartesian xs ys = [(x,y) | x <- xs, y <- ys]

exp :: Monoid a => a -> Int -> a
exp x n = mconcat (replicate n x)