-- |
-- simple key value assocciation list
-- implemented as unordered list of pairs
--
-- Version : $Id: AssocList.hs,v 1.2 2005/05/27 13:15:23 hxml Exp $

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 d k	= fromMaybe d . lookup k

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

lookup1		:: Eq k => k -> AssocList k [e] -> [e]
lookup1 k	= fromMaybe [] . lookup k

-- | test for existence of a key

hasEntry	:: Eq k => k -> AssocList k v -> Bool
hasEntry k	= isJust . lookup 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 k v l	= ( (k,v) : ) $! delEntry k 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	= foldr (.) id . map (uncurry addEntry) . reverse

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

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

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

delEntries	:: Eq k => [k] -> AssocList k v -> AssocList k v
delEntries	= foldl (.) id . map delEntry

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