content: type Boundaries = IntSet
  data Variant = MkVariant
      { variantBoundaries :: Boundaries
      , variantParams     :: [Param]
      }
  
  dispatch :: [Variant] -> [Arg] -> Variant
  dispatch allVariants args = tryLevel 1 (map dropIrrelevantConstraints allCandidates)
      where
      allCandidates   = filter (isCompatibleWith args . variantParams) allVariants
      maxBoundary     = max allBoundaries
      allBoundaries   = union (map variantBoundaries allCandidates)
  
      dropIrrelevantConstraints variant = 
          let (relevant, irrelevant) = variantParams variant `splitAt` finalSemicolon
              finalSemicolon         = (max $ variantBoundaries variant)
           in variant{ variantParams = relevant ++ map dropConstraints irrelevant }
  
      tryLevel count []                   = die "No candidates match at count" count
      tryLevel count [candidate]          = candidate
      tryLevel count candidates
          | count > maxBoundary           = die "Ambiguous candidates" candidates
          | count `elem` allBoundaries    = doLevel count candidates 
          | otherwise                     = tryLevel (count + 1) candidates
  
      doLevel count candidates = case getWinnersUpToLevel count candidates of
          [] -> die "Ambiguous tiebreaking at count" count
          winners
              | all (count `elem` . variantBoundaries) winners 
              -> tryLevel (count + 1) winners
              | losers   <- candidates `difference` winners
              , spoilers <- filter (not . (count `member`) . variantBoundaries) losers
              -> tryLevel (count + 1) (winners `union` spoilers)
  
      getWinnersUpToLevel count candidates
          = foldl1 intersection [ getWinnersForLevel l candidates | l <- 1..count ]
  
      -- A winner is someone who loses to nobody.
      getWinnersForLevel count candidates =
          let arg    = args `idx` count 
              ge x y = greaterOrEqualTo arg (paramIdx x) (paramIdx y)
              paramIdx x  = variantParams x `idx` count
          [ c | c <- candidates, all (\c' -> c `ge` c') candidates ]
  
      -- Incomparable pair = False,False
      -- Comparable equivs = True,True
      greaterOrEqualTo arg param1 param2 = ...
  