 
   """
   @spec scan(t, (element, any -> any)) :: list
-  def scan(enumerable, fun) do
+  def scan(enumerable, fun) when is_function(fun, 2) do
     {res, _} = reduce(enumerable, {[], :first}, R.scan_2(fun))
     :lists.reverse(res)
   end


  """
  @spec max_by(t, (element -> any)) :: element | no_return
  def max_by([h | t], fun) do
    reduce(t, {h, fun.(h)}, fn(entry, {_, fun_max} = old) ->
      fun_entry = fun.(entry)
      if(fun_entry > fun_max, do: {entry, fun_entry}, else: old)


  """
  @spec each(t, (element -> any)) :: :ok
  def each(enumerable, fun) when is_list(enumerable) and is_function(fun, 1) do
    :lists.foreach(fun, enumerable)
    :ok
  end

  def each(enumerable, fun) when is_function(fun, 1) do
    reduce(enumerable, nil, fn(entry, _) ->
      fun.(entry)
      nil
