module Assoc1 where import Products (fork) import Maybe (listToMaybe, fromJust) -- import FiniteMap -- useful to sometimes specify types type IdAt a = a -> a class Eq k => IsAssoc a k where ascEmpty :: a k v ascFromList :: [(k,v)] -> a k v ascToList :: a k v -> [(k,v)] ascAddList :: a k v -> [(k,v)] -> a k v ascLookup :: a k v -> k -> Maybe v ascLookupAll :: a k v -> k -> [v] ascKeys :: a k v -> [k] ascVals :: a k v -> [v] ascMap :: (k -> v -> w) -> a k v -> a k w ascLookupAll a x= [ v | (k,v) <- ascToList a, k == x ] ascLookup a = listToMaybe . ascLookupAll a ascEmpty = ascFromList [] ascLOOKUP :: IsAssoc a k => a k v -> k -> v ascLOOKUP a = fromJust . ascLookup a newtype AscList k v = AL { unAL :: [(k,v)] } instance Eq k => IsAssoc AscList k where ascEmpty = AL [] ascAddList (AL a) y = AL (a ++ y) ascLookup (AL a) x = lookup x a ascKeys = map fst . unAL ascVals = map snd . unAL ascFromList = AL ascToList = unAL ascMap f = AL . map (fork fst (uncurry f)) . unAL {- instance Ord k => IsAssoc FiniteMap k where ascEmpty = emptyFM ascFromList = listToFM ascToList = fmToList ascAddList = addListToFM ascLookup = lookupFM ascKeys = keysFM ascVals = eltsFM ascMap = mapFM -}