 
   """
   @spec reject(Enumerable.t, (element -> as_boolean(term))) :: t
-  def reject(enumerable, f) do
-    Lazy[enumerable: enumerable,
-         fun: fn(f1) ->
-           fn(entry, acc) ->
-             unless f.(entry), do: f1.(entry, acc), else: acc
-           end
-         end]
+  def reject(enum, f) do
+    lazy enum, fn(f1) ->
+      fn(entry, acc) ->
+        unless f.(entry), do: f1.(entry, acc), else: acc
+      end
+    end
   end
 
   @doc """

  `Stream.cycle/1`.
  """

  defrecord Lazy, [:enumerable, :fun, :acc]

  defimpl Enumerable, for: Lazy do
    def reduce(Lazy[] = lazy, acc, fun) do
      do_reduce(lazy, acc, fun, 0)
    end

    def count(Lazy[] = lazy) do
      do_reduce(lazy, 0, fn _, acc -> acc + 1 end, 0)
    end

    def member?(Lazy[] = lazy, value) do
      do_reduce(lazy, false, fn(entry, _) ->
        if entry === value, do: throw({ :stream_lazy, 0, true }), else: false
      end, 0)
    end

    defp do_reduce(Lazy[enumerable: enumerable, fun: f1, acc: nil], acc, fun, nesting) do
      do_reduce(enumerable, acc, f1.(fun), nesting)
    end

    defp do_reduce(Lazy[enumerable: enumerable, fun: f1, acc: side], acc, fun, nesting) do
      do_reduce(enumerable, { acc, side }, f1.(fun, nesting), nesting + 1)
    end

    defp do_reduce(enumerable, acc, fun, nesting) do
      Enumerable.reduce(enumerable, acc, fun) |> remove_nesting(nesting)
    catch
      { :stream_lazy, nesting, res } -> remove_nesting(res, nesting)
    end

    defp remove_nesting(acc, 0),       do: acc
    defp remove_nesting(acc, nesting), do: remove_nesting(elem(acc, 0), nesting - 1)
  end

  @type t :: Lazy.t | (acc, (element, acc -> acc) -> acc)

  """

  @spec flat_map(Enumerable.t, (element -> any)) :: t
  def flat_map(enum, f) do
    lazy enum, fn(f1) ->
      fn(entry, acc) -> do_flat_map(f.(entry), acc, f1) end
    end
  end

  defp do_flat_map(Lazy[] = lazy, acc, f1) do
