-- | Find pairs of most overlapping sets in a given list of sets.
-- A list of objects 'a' plus a function to extract a set 'b'
-- from an object have to be provided.
-- Pairs are held by a 'Pair', the rest is enclosed in 'Single'.
mostOverlapping :: (Ord b, Show a, Show b)
                   => (a -> S.Set b) -> [a] -> [SP a]
mostOverlapping ex xs =
  [ Pair a b | ((_, a), (_, b)) <- pairs ]
  ++ [ Single a | (aid, a) <- ys, S.notMember aid used ]
  where ys = zip [1..] xs
        pairs = map snd $ recur ex 1 ys (const True)
        used = S.fromList $ concat
               [ [aid,bid] | ((aid, _), (bid, _)) <- pairs]
mostOverlapping :: (Ord b, Show a, Show b)
                   => (a -> S.Set b) -> [a] -> [SP a]
mostOverlapping ex xs =
  [ Pair a b | ((_, a), (_, b)) <- pairs ]
  ++ [ Single a | (aid, a) <- ys, S.notMember aid used ]
  where ys = zip [1..] xs
        pairs = map snd $ recur ex 1 ys (const True)
        used = S.fromList $ concat
               [ [aid,bid] | ((aid, _), (bid, _)) <- pairs]
mostOverlapping ex xs =
  [ Pair a b | ((_, a), (_, b)) <- pairs ]
  ++ [ Single a | (aid, a) <- ys, S.notMember aid used ]
  where ys = zip [1..] xs
        pairs = map snd $ recur ex 1 ys (const True)
        used = S.fromList $ concat
               [ [aid,bid] | ((aid, _), (bid, _)) <- pairs]