justCoeffectTypesConvertedVars :: (?globals::Globals)
  => Span -> [(Id, Kind)] -> Checker (Ctxt Type)
justCoeffectTypesConvertedVars s env = do
  let implicitUniversalMadeExplicit = map (\(var, k) -> (var, (k, ForallQ))) env
  env' <- justCoeffectTypesConverted s implicitUniversalMadeExplicit
  return $ stripQuantifiers env'

-- | `ctxtEquals ctxt1 ctxt2` checks if two contexts are equal
--   and the typical pattern is that `ctxt2` represents a specification
--   (i.e. input to checking) and `ctxt1` represents actually usage
justCoeffectTypesConvertedVars :: (?globals::Globals)
  => Span -> [(Id, Kind)] -> Checker (Ctxt Type)
justCoeffectTypesConvertedVars s env = do
  let implicitUniversalMadeExplicit = map (\(var, k) -> (var, (k, ForallQ))) env
  env' <- justCoeffectTypesConverted s implicitUniversalMadeExplicit
  return $ stripQuantifiers env'

-- | `ctxtEquals ctxt1 ctxt2` checks if two contexts are equal
--   and the typical pattern is that `ctxt2` represents a specification
--   (i.e. input to checking) and `ctxt1` represents actually usage
justCoeffectTypesConvertedVars s env = do
  let implicitUniversalMadeExplicit = map (\(var, k) -> (var, (k, ForallQ))) env
  env' <- justCoeffectTypesConverted s implicitUniversalMadeExplicit
  return $ stripQuantifiers env'

-- | `ctxtEquals ctxt1 ctxt2` checks if two contexts are equal
--   and the typical pattern is that `ctxt2` represents a specification
--   (i.e. input to checking) and `ctxt1` represents actually usage