applyTysD doc orig_fun_ty arg_tys
  | n_tvs == n_args     -- The vastly common case
  = substTyWith tvs arg_tys rho_ty
  | n_tvs > n_args      -- Too many for-alls
  = substTyWith (take n_args tvs) arg_tys
                (mkForAllTys (drop n_args tvs) rho_ty)
  | otherwise           -- Too many type args
  = ASSERT2( n_tvs > 0, doc $$ ppr orig_fun_ty $$ ppr arg_tys )        -- Zero case gives infinite loop!
    applyTysD doc (substTyWith tvs (take n_tvs arg_tys) rho_ty)
                  (drop n_tvs arg_tys)
  where
    (tvs, rho_ty) = splitForAllTys orig_fun_ty
    n_tvs  = length tvs
    n_args = length arg_tys
applyTysD doc orig_fun_ty arg_tys
  | n_tvs == n_args     -- The vastly common case
  = substTyWith tvs arg_tys rho_ty
  | n_tvs > n_args      -- Too many for-alls
  = substTyWith (take n_args tvs) arg_tys
                (mkForAllTys (drop n_args tvs) rho_ty)
  | otherwise           -- Too many type args
  = ASSERT2( n_tvs > 0, doc $$ ppr orig_fun_ty $$ ppr arg_tys )        -- Zero case gives infinite loop!
    applyTysD doc (substTyWith tvs (take n_tvs arg_tys) rho_ty)
                  (drop n_tvs arg_tys)
  where
    (tvs, rho_ty) = splitForAllTys orig_fun_ty
    n_tvs  = length tvs
    n_args = length arg_tys
applyTysD doc orig_fun_ty arg_tys
  | n_tvs == n_args     -- The vastly common case
  = substTyWith tvs arg_tys rho_ty
  | n_tvs > n_args      -- Too many for-alls
  = substTyWith (take n_args tvs) arg_tys
                (mkForAllTys (drop n_args tvs) rho_ty)
  | otherwise           -- Too many type args
  = ASSERT2( n_tvs > 0, doc $$ ppr orig_fun_ty $$ ppr arg_tys )        -- Zero case gives infinite loop!
    applyTysD doc (substTyWith tvs (take n_tvs arg_tys) rho_ty)
                  (drop n_tvs arg_tys)
  where
    (tvs, rho_ty) = splitForAllTys orig_fun_ty
    n_tvs  = length tvs
    n_args = length arg_tys