   """
   @spec zip(Enumerable.t(), Enumerable.t()) :: Enumerable.t()
   def zip(enumerable1, enumerable2) do
-    zip([enumerable1, enumerable2])
-  end
-
-  @doc """
-  Lazily zips corresponding elements from two enumerables into a new one, transforming them with
-  the `zip_fun` function as it goes.
-
-  The `zip_fun` will be called with the first element from `enumerable1` and the first
-  element from `enumerable2`, then with the second element from each, and so on until
-  either one of the enumerables completes.
-
-  ## Examples
-
-      iex> concat = Stream.concat(1..3, 4..6)
-      iex> Stream.zip_with(concat, concat, fn a, b -> a + b end) |> Enum.to_list()
-      [2, 4, 6, 8, 10, 12]
-
-  """
-  @doc since: "1.12.0"
-  @spec zip_with(Enumerable.t(), Enumerable.t(), (term, term -> term)) :: Enumerable.t()
-  def zip_with(enumerable1, enumerable2, zip_fun) when is_function(zip_fun, 2) do
-    zip_with([enumerable1, enumerable2], &apply(zip_fun, &1))
+    zip_with(enumerable1, enumerable2, fn left, right -> {left, right} end)
   end
 
   @doc """

       ) do
    [elem | rest] = zip_acc
    next_buffer = [{fun, rest, zip_op} | buffer]
    do_zip_next_tuple(zips, acc, callback, [elem | yielded_elems], next_buffer, zip_fun)
  end

  defp do_zip_next_tuple([] = _zips, acc, callback, yielded_elems, buffer, zip_fun) do
    # "yielded_elems" is a reversed list of results for the current iteration of
    # zipping. That is to say, the nth element from each of the enums being zipped.
    # It needs to be reversed and passed to the zipping function so it can do it's thing.

        {&Enumerable.reduce(enum, &1, step), [], :cont}
      end)

    do_zip_enum(enum_funs, acc, fun, zip_fun)
  end

  # This implementation of do_zip_enum/4 works for any number of streams to zip
  defp do_zip_enum(zips, {:halt, acc}, _fun, _zip_fun) do
    do_zip_close(zips)
    {:halted, acc}
  end

  defp do_zip_enum(zips, {:suspend, acc}, fun, zip_fun) do
    {:suspended, acc, &do_zip_enum(zips, &1, fun, zip_fun)}
  end

  defp do_zip_enum([], {:cont, acc}, _callback, _zip_fun) do
    {:done, acc}
  end

  defp do_zip_enum(zips, {:cont, acc}, callback, zip_fun) do
    try do
      do_zip_next(zips, acc, callback, [], [], zip_fun)
    catch
      kind, reason ->
        do_zip_close(zips)
        :erlang.raise(kind, reason, __STACKTRACE__)
    else
      {:next, buffer, acc} ->
        do_zip_enum(buffer, acc, callback, zip_fun)

      {:done, _acc} = other ->
        other
    end
  end

  # do_zip_next/6 computes the next tuple formed by
  # the next element of each zipped stream.
  defp do_zip_next(
         [{_, [], :halt} | zips],
         acc,
         _callback,
