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, Maybe (Maybe v)
forall a. Maybe a
Nothing)
  f Maybe v
Nothing  = (v
v, Maybe v -> Maybe (Maybe v)
forall a. a -> Maybe a
Just (v -> Maybe v
forall a. a -> Maybe a
Just v
v))
  in Compose ((,) v) Maybe (Map k v) -> (v, Maybe (Map k v))
forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose ((,) v) Maybe (Map k v) -> (v, Maybe (Map k v)))
-> (Map k v -> Compose ((,) v) Maybe (Map k v))
-> Map k v
-> (v, Maybe (Map k v))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe v -> Compose ((,) v) Maybe (Maybe v))
-> k -> Map k v -> Compose ((,) v) Maybe (Map k v)
forall (f :: * -> *) k a.
(Functor f, Ord k) =>
(Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
M.alterF ((v, Maybe (Maybe v)) -> Compose ((,) v) Maybe (Maybe v)
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose ((v, Maybe (Maybe v)) -> Compose ((,) v) Maybe (Maybe v))
-> (Maybe v -> (v, Maybe (Maybe v)))
-> Maybe v
-> Compose ((,) v) Maybe (Maybe v)
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 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
x    = Maybe a
forall a. Maybe a
Nothing
  | Bool
otherwise = a -> Maybe a
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 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== b -> a
f b
y