    {- |
    This module allows to access elements of arrays, sets and finite maps
    like elements of records.
    This is especially useful for working with nested structures
    consisting of arrays, sets, maps and records.

    Maybe we should move it to a separate package,
    then we would not need to import @array@ and @containers@ package.
    -}
    module Data.Accessor.Container
       (array, set,
        mapDefault, mapMaybe,
        intMapDefault, intMapMaybe,
       ) where

    import qualified Data.Accessor.Basic as Accessor

    import Data.Ix (Ix, )
    import qualified Data.Array  as Array
    import qualified Data.Set    as Set
    import qualified Data.Map    as Map
    import qualified Data.IntMap as IntMap

    import Prelude hiding (map)

    array :: Ix i => i -> Accessor.T (Array.Array i e) e
    array :: forall i e. Ix i => i -> T (Array i e) e
    array i
    i = (e -> Array i e -> Array i e)
    -> (Array i e -> e) -> T (Array i e) e
    forall a r. (a -> r -> r) -> (r -> a) -> T r a
    Accessor.fromSetGet (\e
    e Array i e
    a -> Array i e
    a Array i e -> [(i, e)] -> Array i e
    forall i e. Ix i => Array i e -> [(i, e)] -> Array i e
    Array.// [(i
    i,e
    e)]) (Array i e -> i -> e
    forall i e. Ix i => Array i e -> i -> e
    Array.! i
    i)

    {- |
    Treat a Set like a boolean array.
    -}
    set :: Ord a => a -> Accessor.T (Set.Set a) Bool
    set :: forall a. Ord a => a -> T (Set a) Bool
    set a
    a =
       (Bool -> Set a -> Set a) -> (Set a -> Bool) -> T (Set a) Bool
    forall a r. (a -> r -> r) -> (r -> a) -> T r a
    Accessor.fromSetGet
          (\Bool
    b -> if Bool
    b then a -> Set a -> Set a
    forall a. Ord a => a -> Set a -> Set a
    Set.insert a
    a else a -> Set a -> Set a
    forall a. Ord a => a -> Set a -> Set a
    Set.delete a
    a)
          (a -> Set a -> Bool
    forall a. Ord a => a -> Set a -> Bool
    Set.member a
    a)

    {- |
    Treats a finite map like an infinite map,
    where all undefined elements are replaced by a default value.
    -}
    mapDefault :: Ord key => elem -> key -> Accessor.T (Map.Map key elem) elem
    mapDefault :: forall key elem. Ord key => elem -> key -> T (Map key elem) elem
    mapDefault elem
    deflt key
    key =
       (elem -> Map key elem -> Map key elem)
    -> (Map key elem -> elem) -> T (Map key elem) elem
    forall a r. (a -> r -> r) -> (r -> a) -> T r a
    Accessor.fromSetGet (key -> elem -> Map key elem -> Map key elem
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert key
    key) (elem -> key -> Map key elem -> elem
    forall k a. Ord k => a -> k -> Map k a -> a
    Map.findWithDefault elem
    deflt key
    key)

    {- |
    Treats a finite map like an infinite map,
    where all undefined elements are 'Nothing'
    and defined elements are 'Just'.
    -}
    mapMaybe :: Ord key => key -> Accessor.T (Map.Map key elem) (Maybe elem)
    mapMaybe :: forall key elem. Ord key => key -> T (Map key elem) (Maybe elem)
    mapMaybe key
    key =
       (Maybe elem -> Map key elem -> Map key elem)
    -> (Map key elem -> Maybe elem) -> T (Map key elem) (Maybe elem)
    forall a r. (a -> r -> r) -> (r -> a) -> T r a
    Accessor.fromSetGet
          (\Maybe elem
    e Map key elem
    m -> Map key elem
    -> (elem -> Map key elem) -> Maybe elem -> Map key elem
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (key -> Map key elem -> Map key elem
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete key
    key Map key elem
    m) ((elem -> Map key elem -> Map key elem)
    -> Map key elem -> elem -> Map key elem
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (key -> elem -> Map key elem -> Map key elem
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert key
    key) Map key elem
    m) Maybe elem
    e)
          (key -> Map key elem -> Maybe elem
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup key
    key)

    intMapDefault :: elem -> Int -> Accessor.T (IntMap.IntMap elem) elem
    intMapDefault :: forall elem. elem -> Int -> T (IntMap elem) elem
    intMapDefault elem
    deflt Int
    key =
       (elem -> IntMap elem -> IntMap elem)
    -> (IntMap elem -> elem) -> T (IntMap elem) elem
    forall a r. (a -> r -> r) -> (r -> a) -> T r a
    Accessor.fromSetGet (Int -> elem -> IntMap elem -> IntMap elem
    forall a. Int -> a -> IntMap a -> IntMap a
    IntMap.insert Int
    key) (elem -> Int -> IntMap elem -> elem
    forall a. a -> Int -> IntMap a -> a
    IntMap.findWithDefault elem
    deflt Int
    key)

    intMapMaybe :: Int -> Accessor.T (IntMap.IntMap elem) (Maybe elem)
    intMapMaybe :: forall elem. Int -> T (IntMap elem) (Maybe elem)
    intMapMaybe Int
    key =
       (Maybe elem -> IntMap elem -> IntMap elem)
    -> (IntMap elem -> Maybe elem) -> T (IntMap elem) (Maybe elem)
    forall a r. (a -> r -> r) -> (r -> a) -> T r a
    Accessor.fromSetGet
          (\Maybe elem
    e IntMap elem
    m -> IntMap elem -> (elem -> IntMap elem) -> Maybe elem -> IntMap elem
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (Int -> IntMap elem -> IntMap elem
    forall a. Int -> IntMap a -> IntMap a
    IntMap.delete Int
    key IntMap elem
    m) ((elem -> IntMap elem -> IntMap elem)
    -> IntMap elem -> elem -> IntMap elem
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (Int -> elem -> IntMap elem -> IntMap elem
    forall a. Int -> a -> IntMap a -> IntMap a
    IntMap.insert Int
    key) IntMap elem
    m) Maybe elem
    e)
          (Int -> IntMap elem -> Maybe elem
    forall a. Int -> IntMap a -> Maybe a
    IntMap.lookup Int
    key)