type Set a = a -> Bool

empty :: Set a
empty _ = False

insert :: Eq a => a -> Set a -> Set a
insert x m = union (x==) m

remove :: Eq a => a -> Set a -> Set a
remove x m = difference m (x==)

isElem :: a -> Set a -> Bool
isElem = flip ($)

union, intersection, difference :: Set a -> Set a -> Set a
union = lift (||)
intersection = lift (&&)
difference m1 m2 = intersection m1 (complement m2)

lift :: (a -> b -> c) -> (d -> a) -> (d -> b) -> d -> c
lift op f g x = op (f x) (g x)

complement :: Set a -> Set a
complement = (not.)

listToSet :: Eq a => [a] -> Set a
listToSet = flip elem

{- Vor- und Nachteile:

  + einfache Implementierung
  + endliche Darstellung (einiger) unendlicher Mengen als Komplement

  - Zugriffszeit abhaengig von der Anzahl vorhergehender Operationen
  - Teilmengenpraedikat nicht implementierbar (ebenso setToList)

-}

