 
   defp into_protocol(enumerable, collectable) do
     {initial, fun} = Collectable.into(collectable)
-
-    into_protocol(enumerable, initial, fun, fn entry, acc ->
-      fun.(acc, {:cont, entry})
+    reduce_into_protocol(enumerable, initial, fun)
+  end
+
+  defp reduce_into_protocol(enumerable, initial, fun) do
+    try do
+      wrapped_reduce_into_protocol(enumerable, initial, fun)
+    catch
+      kind, reason ->
+        fun.(initial, :halt)
+        :erlang.raise(kind, reason, __STACKTRACE__)
+    else
+      acc -> fun.(acc, :done)
+    end
+  end
+
+  defp wrapped_reduce_into_protocol(enumerable, initial, fun)
+       when is_list(enumerable) do
+    :lists.foldl(fn x, acc -> fun.(acc, {:cont, x}) end, initial, enumerable)
+  end
+
+  defp wrapped_reduce_into_protocol(enumerable, initial, fun) do
+    enumerable
+    |> Enumerable.reduce({:cont, initial}, fn x, acc ->
+      {:cont, fun.(acc, {:cont, x})}
     end)
+    |> elem(1)
   end
 
   @doc """


  defp into_protocol(enumerable, collectable, transform) do
    {initial, fun} = Collectable.into(collectable)

    into_protocol(enumerable, initial, fun, fn entry, acc ->
      fun.(acc, {:cont, transform.(entry)})
    end)
  end

  defp into_protocol(enumerable, initial, fun, callback) do
    try do
      reduce(enumerable, initial, callback)
    catch
      kind, reason ->
        fun.(initial, :halt)

    else
      acc -> fun.(acc, :done)
    end
  end

  defp wrapped_reduce_into_protocol(enumerable, initial, transform, fun)
       when is_list(enumerable) do
    :lists.foldl(fn x, acc -> fun.(acc, {:cont, transform.(x)}) end, initial, enumerable)
  end

  defp wrapped_reduce_into_protocol(enumerable, initial, transform, fun) do
    enumerable
    |> Enumerable.reduce({:cont, initial}, fn x, acc ->
      {:cont, fun.(acc, {:cont, transform.(x)})}
    end)
    |> elem(1)
  end

  @doc """
