-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Syntax sugar for defining maps
--   
--   Haskell's canonical list of tuples syntax for defining maps is not
--   very convenient and also has ambiguous semantics. This package
--   leverages do notation to create a lighter syntax that makes semantics
--   explicit and also allows the option of fail-fast handling of duplicate
--   keys.
@package map-syntax
@version 0.3


-- | An API implementing a convenient syntax for defining maps. This module
--   was born from the observation that a list of tuples is semantically
--   ambiguous about how duplicate keys should be handled. Additionally,
--   the syntax is inherently rather cumbersome and difficult to work with.
--   This API takes advantage of do notation to provide a very light syntax
--   for defining maps while at the same time eliminating the semantic
--   ambiguity of alists.
--   
--   Here's an example:
--   
--   <pre>
--   foo :: MapSyntax Text Text
--   foo = do
--     "firstName" ## "John"
--     "lastName"  ## "Smith"
--   </pre>
module Data.Map.Syntax

-- | A monad providing convenient syntax for defining maps.
data MapSyntaxM k v a

-- | Convenient type alias that will probably be used most of the time.
type MapSyntax k v = MapSyntaxM k v ()

-- | Runs the MapSyntaxM monad to generate a map.
runMap :: Ord k => MapSyntaxM k v a -> Either [k] (Map k v)

-- | Forces an entry to be added. If the key already exists, its value is
--   overwritten.
(##) :: k -> v -> MapSyntax k v
infixr 0 ##

-- | Tries to add an entry, but if the key already exists, then
--   <a>runMap</a> will return a Left with the list of offending keys. This
--   may be useful if name collisions are bad and you want to know when
--   they occur.
(#!) :: k -> v -> MapSyntax k v
infixr 0 #!

-- | Inserts into the map only if the key does not already exist. If the
--   key does exist, it silently continues without overwriting or
--   generating an error indication.
(#?) :: k -> v -> MapSyntax k v
infixr 0 #?

-- | Maps a function over all the keys.
mapK :: (k1 -> k2) -> MapSyntaxM k1 v a -> MapSyntax k2 v

-- | Maps a function over all the values.
mapV :: (v1 -> v2) -> MapSyntaxM k v1 a -> MapSyntax k v2

-- | Runs the MapSyntaxM monad to generate a map.
runMapSyntax :: Monoid map => (k -> map -> Maybe v) -> (k -> v -> map -> map) -> MapSyntaxM k v a -> Either [k] map

-- | Runs the MapSyntaxM monad to generate a map. This function gives you
--   the full power of insertWith when duplicate keys are encountered.
--   
--   Example:
--   
--   <pre>
--   runMapSyntax' (\k new_val old_val -&gt; Just $ old_val ++ new_val)
--   </pre>
runMapSyntax' :: Monoid map => (k -> v -> v -> Maybe v) -> (k -> map -> Maybe v) -> (k -> v -> map -> map) -> MapSyntaxM k v a -> Either [k] map

-- | Strategy to use for duplicates
data DupStrat
Replace :: DupStrat
Ignore :: DupStrat
Error :: DupStrat

-- | Representation of an indivdual item in a map
data ItemRep k v
ItemRep :: DupStrat -> k -> v -> ItemRep k v
[irStrat] :: ItemRep k v -> DupStrat
[irKey] :: ItemRep k v -> k
[irVal] :: ItemRep k v -> v

-- | Low level add function for adding a specific DupStrat, key, and value.
addStrat :: DupStrat -> k -> v -> MapSyntax k v
instance GHC.Internal.Base.Applicative (Data.Map.Syntax.MapSyntaxM k v)
instance GHC.Internal.Base.Functor (Data.Map.Syntax.MapSyntaxM k v)
instance GHC.Internal.Base.Monad (Data.Map.Syntax.MapSyntaxM k v)
instance GHC.Internal.Base.Monoid (Data.Map.Syntax.MapSyntax k v)
instance GHC.Internal.Base.Semigroup (Data.Map.Syntax.MapSyntax k v)
