-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Applicative maps -- -- This package provides a Defaultable type constructor that wraps -- any Map-like type to add an optional default value. Wrapping a -- Map-like type in this way permits a valid Applicative -- instance, so you can think of this as an "Applicative map" -- package. @package defaultable-map @version 1.0.2 -- | This module provides a Defaultable type constructor for -- extending Map-like types with a valid Applicative and -- Alternative instance. If you're looking for an -- "Applicative Map" then you are in the right place! -- -- The Defaultable type constructor can be used to wrap any -- Map-like, such as Data.Map.Map or -- Data.HashMap.HashMap. -- -- For convenience, this module also includes a concrete API wrapping -- Data.Map.Map since that's the most common case. -- If you are interested in a more general API that works with other -- Map types then check out the Defaultable.Map.Generalized -- module. -- -- The Applicative instance enables the use of the -- ApplicativeDo language extension. For example, suppose that -- you created the following three Defaultable Maps: -- --
--   firstNames, lastNames, handles :: Defaultable (Map Int) String
--   firstNames = fromList [(0, "Gabriella"    ), (1, "Oscar"), (2, "Edgar"    )                  ]
--   lastNames  = fromList [(0, "Gonzalez"     ),               (2, "Codd"     ), (3, "Bryant"   )]
--   handles    = fromList [(0, "GabriellaG439"), (1, "posco"),                   (3, "avibryant")]
--   
-- -- Then you can use ApplicativeDo notation to create an "inner -- join" of these various maps, like this: -- --
--   >>> :set -XApplicativeDo
--   
--   >>> do firstName <- firstNames; lastName <- lastNames; return (firstName, lastName)
--   Defaultable (fromList [(0,("Gabriella","Gonzalez")),(2,("Edgar","Codd"))]) Nothing
--   
-- -- … and you can join as many of these maps as you want by adding -- statements to these ApplicativeDo blocks: -- --
--   {-# LANGUAGE ApplicativeDo #-}
--   
--   innerJoins :: Defaultable (Map Int) (String, String, String)
--   innerJoins = do
--       firstName <- firstNames
--       lastName  <- lastNames
--       handles   <- handles
--       return (firstName, lastName, handles)
--   
-- --
--   >>> innerJoins
--   Defaultable (fromList [(0,("Gabriella","Gonzalez","GabriellaG439"))]) Nothing
--   
-- -- The Alternative instance for Defaultable is also -- important, too, because you can use Alternative operations to -- create "left/right joins" and something similar to an outer join, like -- this: -- --
--   leftJoin :: Defaultable (Map Int) (String, Maybe String)
--   leftJoin = do
--       firstName <- firstNames
--       lastName  <- optional lastNames
--       return (firstName, lastName)
--   
--   rightJoin :: Defaultable (Map Int) (Maybe String, String)
--   rightJoin = do
--       firstName <- optional firstNames
--       lastName  <- lastNames
--       return (firstName, lastName)
--   
--   
--   similarToOuterJoin :: Defaultable (Map Int) (Maybe String, Maybe String)
--   similarToOuterJoin = do
--       firstName <- optional firstNames
--       lastName  <- optional lastNames
--       return (firstName, lastName)
--   
-- --
--   >>> leftJoin
--   Defaultable (fromList [(0,("Gabriella",Just "Gonzalez")),(1,("Oscar",Nothing)),(2,("Edgar",Just "Codd"))]) Nothing
--   
--   >>> rightJoin
--   Defaultable (fromList [(0,(Just "Gabriella","Gonzalez")),(2,(Just "Edgar","Codd")),(3,(Nothing,"Bryant"))]) Nothing
--   
--   >>> similarToOuterJoin
--   Defaultable (fromList [(0,(Just "Gabriella",Just "Gonzalez")),(1,(Just "Oscar",Nothing)),(2,(Just "Edgar",Just "Codd")),(3,(Nothing,Just "Bryant"))]) (Just (Nothing,Nothing))
--   
-- -- You can also do more interesting multiway joins where any combiination -- of the inputs may be optional: -- --
--   complexJoin :: Defaultable (Map Int) (Maybe String, String, Maybe String)
--   complexJoin = do
--       firstName <- optional firstNames
--       lastName  <- lastNames
--       handle    <- optional handles
--       return (firstName, lastName, handle)
--   
-- --
--   >>> complexJoin
--   Defaultable (fromList [(0,(Just "Gabriella","Gonzalez",Just "GabrielG439")),(2,(Just "Edgar","Codd",Nothing)),(3,(Nothing,"Bryant",Just "avibryant"))]) Nothing
--   
module Defaultable.Map -- | A Defaultable type is a Map-like type that is extended -- with an optional default value. This default value can be used as a -- fallback if a lookup into the Map-like type does not find a -- matching key. -- -- The type variables are: -- -- -- -- For example, you will typically have a type like -- Defaultable (Map key) value or -- Defaultable IntMap value. -- -- You can build a Defaultable value using: -- -- -- -- You can transform and combine Defaultable values using: -- -- -- -- You can query a Defaultable value using: -- -- -- -- Note that the Applicative instance for this type is only valid -- for map type constructors that satisfy the following extra -- law: -- --
--   Given:
--   
--   • mf :: map (a -> b)
--   • mx :: map a
--   • kf :: (a -> b) -> c
--   • kx :: a -> c
--   
--     (mf <.> mx) <> fmap kf mf <> fmap kx mx
--   = (mf <.> mx) <> fmap kx mx <> fmap kf mf
--   
-- -- … where map is the first type parameter that implements -- Apply and Monoid. -- -- The intuition here is if that map is a Map-like type -- then we can think of those three expressions as having a set of keys -- associated with them, such that: -- --
--   Given:
--   
--   • keys :: map a -> Set key
--   
--   keys (mf <.> mx) = keys (fmap kf mf) `intersection` keys (fmap kx mx)
--   
-- -- So normally the following equality would not be true: -- --
--     fmap kf mf <> fmap kx mx
--   = fmap kx mx <> fmap kf mf
--   
-- -- … because the result would change if there was a key collision. Then -- the order in which we union (<>) the two maps would -- change the result. -- -- However, if you union yet another map (mf <.> -- mx) that shadows the colliding keys then result remains the same. data Defaultable map value Defaultable :: map value -> Maybe value -> Defaultable map value -- | A Map from keys k to values a. -- -- The Semigroup operation for Map is union, which -- prefers values from the left operand. If m1 maps a key -- k to a value a1, and m2 maps the same key -- to a different value a2, then their union m1 <> -- m2 maps k to a1. data Map k a -- | Create a Defaultable Map from a Map -- --
--   >>> fromMap (Map.fromList [('A',1),('B',2),('B',3)])
--   Defaultable (fromList [('A',1),('B',3)]) Nothing
--   
fromMap :: Map key value -> Defaultable (Map key) value -- | Create a Defaultable Map from a single key-value pair -- --
--   >>> singleton ('A', 1)
--   Defaultable (fromList [('A',1)]) Nothing
--   
singleton :: (key, value) -> Defaultable (Map key) value -- | Create a Defaultable Map from a list of key-value pairs -- --
--   >>> fromList [('A',1),('B',2),('B',3)]
--   Defaultable (fromList [('A',1),('B',3)]) Nothing
--   
fromList :: Ord key => [(key, value)] -> Defaultable (Map key) value -- | Insert a key-value pair into a Defaultable Map -- --
--   >>> let example = fromList [('A', 1)]
--   
--   >>> insert ('B', 2) example
--   Defaultable (fromList [('A',1),('B',2)]) Nothing
--   
--   >>> insert ('A', 0) example
--   Defaultable (fromList [('A',0)]) Nothing
--   
-- -- For bulk updates, you should instead use -- fromList/fromMap with (<|>): -- --
--   >>> fromList [('A',0),('B', 2), ('C', 3)] <|> example
--   Defaultable (fromList [('A',0),('B',2),('C',3)]) Nothing
--   
insert :: Ord key => (key, value) -> Defaultable (Map key) value -> Defaultable (Map key) value -- | Add a default value to a Defaultable Map that is -- returned as a fallback if a lookup cannot find a matching key -- --
--   >>> let example = fromList [('A',1)] `withDefault` 2
--   
--   >>> lookup 'A' example
--   Just 1
--   
--   >>> lookup 'B' example
--   Just 2
--   
withDefault :: Ord key => Defaultable (Map key) value -> value -> Defaultable (Map key) value -- | Lookup the value at a key in the map -- -- If the key is missing this falls back to returning the default value -- if present -- -- lookup is an Monad morphism, meaning that lookup -- distributes over Monad operatiorns: -- --
--   lookup (return x) = return x
--   
--   lookup (do x <- m; f x) = do x <- lookup m; lookup (f x)
--   
-- -- lookup is also an Alternative morphism, meaning that -- lookup distributes over Alternative operations: -- --
--   lookup empty = empty
--   
--   lookup (l <|> r) = lookup l <|> lookup r
--   
-- --
--   >>> let example = fromList [('A',1)]
--   
--   >>> lookup 'A' example
--   Just 1
--   
--   >>> lookup 'B' example
--   Nothing
--   
--   >>> lookup 'B' (example `withDefault` 2)
--   Just 2
--   
lookup :: Ord key => key -> Defaultable (Map key) value -> Maybe value -- | Extract the underlying map from a Defaultable map toMap :: Defaultable (Map key) value -> Map key value -- | Extract the default value from a Defaultable map toDefault :: Defaultable (Map key) value -> Maybe value instance (Control.DeepSeq.NFData value, Control.DeepSeq.NFData (map value)) => Control.DeepSeq.NFData (Defaultable.Map.Defaultable map value) instance Data.Traversable.Traversable map => Data.Traversable.Traversable (Defaultable.Map.Defaultable map) instance (GHC.Show.Show value, GHC.Show.Show (map value)) => GHC.Show.Show (Defaultable.Map.Defaultable map value) instance (GHC.Classes.Ord value, GHC.Classes.Ord (map value)) => GHC.Classes.Ord (Defaultable.Map.Defaultable map value) instance GHC.Generics.Generic1 (Defaultable.Map.Defaultable map) instance GHC.Generics.Generic (Defaultable.Map.Defaultable map value) instance GHC.Base.Functor map => GHC.Base.Functor (Defaultable.Map.Defaultable map) instance Data.Foldable.Foldable map => Data.Foldable.Foldable (Defaultable.Map.Defaultable map) instance (GHC.Classes.Eq value, GHC.Classes.Eq (map value)) => GHC.Classes.Eq (Defaultable.Map.Defaultable map value) instance (Data.Typeable.Internal.Typeable map, Data.Data.Data value, Data.Data.Data (map value)) => Data.Data.Data (Defaultable.Map.Defaultable map value) instance (Data.Functor.Bind.Class.Apply map, forall a. GHC.Base.Monoid (map a)) => Data.Functor.Bind.Class.Apply (Defaultable.Map.Defaultable map) instance (Data.Functor.Bind.Class.Apply map, forall a. GHC.Base.Monoid (map a)) => GHC.Base.Applicative (Defaultable.Map.Defaultable map) instance (Data.Functor.Bind.Class.Apply map, forall a. GHC.Base.Monoid (map a)) => Data.Functor.Alt.Alt (Defaultable.Map.Defaultable map) instance (Data.Functor.Bind.Class.Apply map, forall a. GHC.Base.Monoid (map a)) => GHC.Base.Alternative (Defaultable.Map.Defaultable map) instance (Data.Functor.Bind.Class.Apply map, forall a. GHC.Base.Monoid (map a), GHC.Base.Semigroup value) => GHC.Base.Semigroup (Defaultable.Map.Defaultable map value) instance (Data.Functor.Bind.Class.Apply map, forall a. GHC.Base.Monoid (map a), GHC.Base.Monoid value) => GHC.Base.Monoid (Defaultable.Map.Defaultable map value) -- | This module exports an API that is similar to Defaultable.Map, -- except the utilities have been generalized further to work with any -- Map-like type. -- -- The only utility that cannot be generalized in this way is -- lookup, so that is the only function missing from this module. -- Other than the missing lookup function, this module is a -- drop-in replacement for the Defaultable.Map module. -- -- Also, keep in mind that these generalized utilities may have worse -- type inference (especially you omit type annotations) and in some -- cases might also be more inefficient. If this is an issue for you then -- you'll need to create your own local module specializing these -- utilities to your Map-like type of interest. module Defaultable.Map.Generalized -- | A Defaultable type is a Map-like type that is extended -- with an optional default value. This default value can be used as a -- fallback if a lookup into the Map-like type does not find a -- matching key. -- -- The type variables are: -- -- -- -- For example, you will typically have a type like -- Defaultable (Map key) value or -- Defaultable IntMap value. -- -- You can build a Defaultable value using: -- -- -- -- You can transform and combine Defaultable values using: -- -- -- -- You can query a Defaultable value using: -- -- -- -- Note that the Applicative instance for this type is only valid -- for map type constructors that satisfy the following extra -- law: -- --
--   Given:
--   
--   • mf :: map (a -> b)
--   • mx :: map a
--   • kf :: (a -> b) -> c
--   • kx :: a -> c
--   
--     (mf <.> mx) <> fmap kf mf <> fmap kx mx
--   = (mf <.> mx) <> fmap kx mx <> fmap kf mf
--   
-- -- … where map is the first type parameter that implements -- Apply and Monoid. -- -- The intuition here is if that map is a Map-like type -- then we can think of those three expressions as having a set of keys -- associated with them, such that: -- --
--   Given:
--   
--   • keys :: map a -> Set key
--   
--   keys (mf <.> mx) = keys (fmap kf mf) `intersection` keys (fmap kx mx)
--   
-- -- So normally the following equality would not be true: -- --
--     fmap kf mf <> fmap kx mx
--   = fmap kx mx <> fmap kf mf
--   
-- -- … because the result would change if there was a key collision. Then -- the order in which we union (<>) the two maps would -- change the result. -- -- However, if you union yet another map (mf <.> -- mx) that shadows the colliding keys then result remains the same. data Defaultable map value Defaultable :: map value -> Maybe value -> Defaultable map value -- | Generalized version of fromMap fromMap :: map value -> Defaultable map value -- | Generalized version of singleton singleton :: IsList (map value) => Item (map value) -> Defaultable map value -- | Generalized version of fromList fromList :: IsList (map value) => [Item (map value)] -> Defaultable map value -- | Generalized version of insert insert :: (IsList (map value), Apply map, forall a. Monoid (map a)) => Item (map value) -> Defaultable map value -> Defaultable map value -- | Generalized version of withDefault withDefault :: (Apply map, forall a. Monoid (map a)) => Defaultable map value -> value -> Defaultable map value -- | Generalized version of toMap toMap :: Defaultable map value -> map value -- | Generalized version of toDefault toDefault :: Defaultable map value -> Maybe value