-- |Algebra for checking whether a variable is contained in a term, except those
-- that are bound.
variablesAlg :: (Ord v, HasVars f v, HTraversable f) => Alg f (K (Set v))
variablesAlg t = K $ hfoldlBoundVars run local t
    where local = case isVar t of
                    Just v -> Set.singleton v
                    Nothing -> Set.empty
          run acc bvars (K vars) = acc `Set.union` (vars `Set.difference` bvars)

{-| This function computes the set of variables occurring in a context. -}
variablesAlg :: (Ord v, HasVars f v, HTraversable f) => Alg f (K (Set v))
variablesAlg t = K $ hfoldlBoundVars run local t
    where local = case isVar t of
                    Just v -> Set.singleton v
                    Nothing -> Set.empty
          run acc bvars (K vars) = acc `Set.union` (vars `Set.difference` bvars)

{-| This function computes the set of variables occurring in a context. -}
variablesAlg t = K $ hfoldlBoundVars run local t
    where local = case isVar t of
                    Just v -> Set.singleton v
                    Nothing -> Set.empty
          run acc bvars (K vars) = acc `Set.union` (vars `Set.difference` bvars)

{-| This function computes the set of variables occurring in a context. -}