content: module Infernu.Lib where
  
  import           Data.Maybe                (fromMaybe)
  import           Data.Map.Strict             (Map)
  import qualified Data.Map.Strict             as Map
  import           Data.Set                  (Set)
  import qualified Data.Set                  as Set
  
  import           Infernu.Prelude
  
  
  matchZip :: [a] -> [b] -> Maybe [(a,b)]
  matchZip [] [] = Just []
  matchZip (_:_) [] = Nothing
  matchZip [] (_:_) = Nothing
  matchZip (x:xs) (y:ys) = fmap ((x,y):) $ matchZip xs ys
  
  safeLookup :: Eq a => [(a,a)] -> a -> a
  safeLookup assoc n = fromMaybe n $ lookup n assoc
  
  -- | Creates an inverse map. Multiple keys mapping to the same values are collected into Sets.
  --
  -- >>> flipMap $ Map.fromList [(1,2),(2,2)]
  -- fromList [(2,fromList [1,2])]
  flipMap :: (Ord k, Ord v) => Map k v -> Map v (Set k)
  flipMap m = Map.foldrWithKey (\k v m' -> Map.alter (Just . addKeyToSet' k) v m') Map.empty m
    where addKeyToSet' k Nothing = Set.singleton k
          addKeyToSet' k (Just s) = Set.insert k s
  
  splatMap :: Ord k => Map (Set k) a -> Map k a
  splatMap m = Map.foldrWithKey (\ks v m' -> foldr (\k m'' -> Map.insert k v m'') m' (Set.toList ks)) Map.empty m
  
  