 
   """
   @spec take(Enumerable.t, non_neg_integer) :: t
-  def take(_enumerable, 0), do: Lazy[enumerable: [], fun: &(&1)]
-
-  def take(enumerable, n) when n > 0 do
-    Lazy[enumerable: enumerable,
-         fun: fn(f1, nesting) ->
-           fn(entry, { acc, n }) ->
-             res = f1.(entry, acc)
-             if n > 1, do: { res, n-1 }, else: throw { :stream_lazy, nesting, res }
-           end
-         end,
-         acc: n]
-  end
+  def take(enum, n) when n > 0 do
+    lazy enum, n, fn(f1) ->
+      fn(entry, [h,n|t]) ->
+        [h|t] = f1.(entry, [h|t])
+        if n > 1, do: [h,n-1|t], else: throw { :stream_lazy, h }
+      end
+    end
+  end
+
+  def take(_enum, 0), do: Lazy[enum: [], funs: [&(&1)]]
 
   @doc """
   Lazily takes elements of the enumerable while the given

  """

  @spec flat_map(Enumerable.t, (element -> any)) :: t
  def flat_map(enumerable, f) do
    Lazy[enumerable: enumerable,
         fun: fn(f1) ->
           fn(entry, acc) -> do_flat_map(f.(entry), acc, f1) end
         end]
  end

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


  """
  @spec drop_while(Enumerable.t, (element -> as_boolean(term))) :: t
  def drop_while(enum, f) do
    lazy enum, true, fn(f1) ->
      fn
        entry, [h,true|t] = orig ->
          if f.(entry) do
            orig
          else
            [h|t] = f1.(entry, [h|t])
            [h,false|t]
          end
        entry, [h,false|t] ->
          [h|t] = f1.(entry, [h|t])
          [h,false|t]
      end
    end
  end

  @doc """
