module Data.Mapping.Util where

import Data.Functor.Compose (Compose(..))
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M


-- | inserts key with value only if absent, returns map if changed
insertIfAbsent :: Ord k => k -> v -> Map k v -> (v, Maybe (Map k v))
insertIfAbsent :: forall k v. Ord k => k -> v -> Map k v -> (v, Maybe (Map k v))
insertIfAbsent k
k v
v = let
  f :: Maybe v -> (v, Maybe (Maybe v))
f (Just v
x) = (v
x, forall a. Maybe a
Nothing)
  f Maybe v
Nothing  = (v
v, forall a. a -> Maybe a
Just (forall a. a -> Maybe a
Just v
v))
  in forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) k a.
(Functor f, Ord k) =>
(Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
M.alterF (forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe v -> (v, Maybe (Maybe v))
f) k
k


-- | For use in maps where we don't want to store default values
nonDefault :: Eq a => a -> a -> Maybe a
nonDefault :: forall a. Eq a => a -> a -> Maybe a
nonDefault a
d a
x
  | a
d forall a. Eq a => a -> a -> Bool
== a
x    = forall a. Maybe a
Nothing
  | Bool
otherwise = forall a. a -> Maybe a
Just a
x


-- | Helper function (not exported)
equating :: Eq a => (b -> a) -> b -> b -> Bool
equating :: forall a b. Eq a => (b -> a) -> b -> b -> Bool
equating b -> a
f b
x b
y = b -> a
f b
x forall a. Eq a => a -> a -> Bool
== b -> a
f b
y