    -- ------------------------------------------------------------

    {- |
       Module     : Data.AssocList
       Copyright  : Copyright (C) 2010 Uwe Schmidt
       License    : MIT

       Maintainer : Uwe Schmidt (uwe@fh-wedel.de)
       Stability  : stable
       Portability: portable

       Simple key value assocciation list
       implemented as unordered list of pairs

    -}

    -- ------------------------------------------------------------

    module Data.AssocList
        ( module Data.AssocList
        )
    where

    import Data.Maybe

    type AssocList k v = [(k, v)]

    -- lookup       = lookup from Prelude

    -- | lookup with default value

    lookupDef       :: Eq k => v -> k -> AssocList k v -> v
    lookupDef :: forall k v. Eq k => v -> k -> AssocList k v -> v
    lookupDef v
    d k
    k   = v -> Maybe v -> v
    forall a. a -> Maybe a -> a
    fromMaybe v
    d (Maybe v -> v) -> (AssocList k v -> Maybe v) -> AssocList k v -> v
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . k -> AssocList k v -> Maybe v
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup k
    k

    -- | lookup with empty list (empty string) as default value

    lookup1         :: Eq k => k -> AssocList k [e] -> [e]
    lookup1 :: forall k e. Eq k => k -> AssocList k [e] -> [e]
    lookup1 k
    k       = [e] -> Maybe [e] -> [e]
    forall a. a -> Maybe a -> a
    fromMaybe [] (Maybe [e] -> [e])
    -> (AssocList k [e] -> Maybe [e]) -> AssocList k [e] -> [e]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . k -> AssocList k [e] -> Maybe [e]
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup k
    k

    -- | test for existence of a key

    hasEntry        :: Eq k => k -> AssocList k v -> Bool
    hasEntry :: forall k v. Eq k => k -> AssocList k v -> Bool
    hasEntry k
    k      = Maybe v -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe v -> Bool)
    -> (AssocList k v -> Maybe v) -> AssocList k v -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . k -> AssocList k v -> Maybe v
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup k
    k

    -- | add an entry, remove an existing entry before adding the new one at the top of the list, addEntry is strict

    addEntry        :: Eq k => k -> v -> AssocList k v -> AssocList k v
    addEntry :: forall k v. Eq k => k -> v -> AssocList k v -> AssocList k v
    addEntry k
    k v
    v AssocList k v
    l  = ( (k
    k,v
    v) (k, v) -> AssocList k v -> AssocList k v
    forall a. a -> [a] -> [a]
    : ) (AssocList k v -> AssocList k v) -> AssocList k v -> AssocList k v
    forall a b. (a -> b) -> a -> b
    $! k -> AssocList k v -> AssocList k v
    forall k v. Eq k => k -> AssocList k v -> AssocList k v
    delEntry k
    k AssocList k v
    l

     -- let l' = delEntry k l in seq l' ((k, v) : l')

    -- | add a whole list of entries with 'addEntry'

    addEntries      :: Eq k => AssocList k v -> AssocList k v -> AssocList k v
    addEntries :: forall k v. Eq k => AssocList k v -> AssocList k v -> AssocList k v
    addEntries      = ((AssocList k v -> AssocList k v)
     -> (AssocList k v -> AssocList k v)
     -> AssocList k v
     -> AssocList k v)
    -> (AssocList k v -> AssocList k v)
    -> [AssocList k v -> AssocList k v]
    -> AssocList k v
    -> AssocList k v
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (AssocList k v -> AssocList k v)
    -> (AssocList k v -> AssocList k v)
    -> AssocList k v
    -> AssocList k v
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.) AssocList k v -> AssocList k v
    forall a. a -> a
    id ([AssocList k v -> AssocList k v]
     -> AssocList k v -> AssocList k v)
    -> (AssocList k v -> [AssocList k v -> AssocList k v])
    -> AssocList k v
    -> AssocList k v
    -> AssocList k v
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((k, v) -> AssocList k v -> AssocList k v)
    -> AssocList k v -> [AssocList k v -> AssocList k v]
    forall a b. (a -> b) -> [a] -> [b]
    map ((k -> v -> AssocList k v -> AssocList k v)
    -> (k, v) -> AssocList k v -> AssocList k v
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry k -> v -> AssocList k v -> AssocList k v
    forall k v. Eq k => k -> v -> AssocList k v -> AssocList k v
    addEntry) (AssocList k v -> [AssocList k v -> AssocList k v])
    -> (AssocList k v -> AssocList k v)
    -> AssocList k v
    -> [AssocList k v -> AssocList k v]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . AssocList k v -> AssocList k v
    forall a. [a] -> [a]
    reverse

    -- | delete an entry, delEntry is strict
    delEntry        :: Eq k => k -> AssocList k v -> AssocList k v
    delEntry :: forall k v. Eq k => k -> AssocList k v -> AssocList k v
    delEntry k
    _ []   = []
    delEntry k
    k (x :: (k, v)
    x@(k
    k1,v
    _) : [(k, v)]
    rest)
        | k
    k k -> k -> Bool
    forall a. Eq a => a -> a -> Bool
    == k
    k1   = [(k, v)]
    rest
        | Bool
    otherwise = ( (k, v)
    x (k, v) -> [(k, v)] -> [(k, v)]
    forall a. a -> [a] -> [a]
    : ) ([(k, v)] -> [(k, v)]) -> [(k, v)] -> [(k, v)]
    forall a b. (a -> b) -> a -> b
    $! k -> [(k, v)] -> [(k, v)]
    forall k v. Eq k => k -> AssocList k v -> AssocList k v
    delEntry k
    k [(k, v)]
    rest

    -- delEntry k   = filter ((/= k) . fst)

    -- | delete a list of entries with 'delEntry'

    delEntries      :: Eq k => [k] -> AssocList k v -> AssocList k v
    delEntries :: forall k v. Eq k => [k] -> AssocList k v -> AssocList k v
    delEntries      = ((AssocList k v -> AssocList k v)
     -> (AssocList k v -> AssocList k v)
     -> AssocList k v
     -> AssocList k v)
    -> (AssocList k v -> AssocList k v)
    -> [AssocList k v -> AssocList k v]
    -> AssocList k v
    -> AssocList k v
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl (AssocList k v -> AssocList k v)
    -> (AssocList k v -> AssocList k v)
    -> AssocList k v
    -> AssocList k v
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.) AssocList k v -> AssocList k v
    forall a. a -> a
    id ([AssocList k v -> AssocList k v]
     -> AssocList k v -> AssocList k v)
    -> ([k] -> [AssocList k v -> AssocList k v])
    -> [k]
    -> AssocList k v
    -> AssocList k v
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (k -> AssocList k v -> AssocList k v)
    -> [k] -> [AssocList k v -> AssocList k v]
    forall a b. (a -> b) -> [a] -> [b]
    map k -> AssocList k v -> AssocList k v
    forall k v. Eq k => k -> AssocList k v -> AssocList k v
    delEntry

    -- -----------------------------------------------------------------------------