+-- Assumes that the arguments contain no duplicates
+unionLists xs ys = [x | x <- xs, isn'tIn "unionLists" x ys] ++ ys
+
+minusList :: (Eq a) => [a] -> [a] -> [a]
+-- Everything in the first list that is not in the second list:
+minusList xs ys = [ x | x <- xs, isn'tIn "minusList" x ys]
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection[Utils-assoc]{Association lists}
+%* *
+%************************************************************************
+
+Inefficient finite maps based on association lists and equality.
+
+\begin{code}
+type Assoc a b = [(a,b)] -- A finite mapping based on equality and association lists
+
+emptyAssoc :: Assoc a b
+unitAssoc :: a -> b -> Assoc a b
+assocElts :: Assoc a b -> [(a,b)]
+assoc :: (Eq a) => String -> Assoc a b -> a -> b
+assocDefault :: (Eq a) => b -> Assoc a b -> a -> b
+assocUsing :: (a -> a -> Bool) -> String -> Assoc a b -> a -> b
+assocMaybe :: (Eq a) => Assoc a b -> a -> Maybe b
+assocDefaultUsing :: (a -> a -> Bool) -> b -> Assoc a b -> a -> b
+mapAssoc :: (b -> c) -> Assoc a b -> Assoc a c
+extendAssoc_C :: (Eq a) => (b -> b -> b) -> Assoc a b -> (a,b) -> Assoc a b
+plusAssoc_C :: (Eq a) => (b -> b -> b) -> Assoc a b -> Assoc a b -> Assoc a b
+ -- combining fn takes (old->new->result)
+
+emptyAssoc = []
+unitAssoc a b = [(a,b)]
+assocElts xs = xs
+
+assocDefaultUsing eq deflt ((k,v) : rest) key
+ | k `eq` key = v
+ | otherwise = assocDefaultUsing eq deflt rest key
+
+assocDefaultUsing eq deflt [] key = deflt
+
+assoc crash_msg list key = assocDefaultUsing (==) (panic ("Failed in assoc: " ++ crash_msg)) list key
+assocDefault deflt list key = assocDefaultUsing (==) deflt list key
+assocUsing eq crash_msg list key = assocDefaultUsing eq (panic ("Failed in assoc: " ++ crash_msg)) list key
+
+assocMaybe alist key
+ = lookup alist