Given the

{ok, result} | {:error, result}

convention and the beautiful nature of piping, I often find myself looking 
for an elegant way to "strain" out all of the {:error _} results in the 
middle of a pipe so I can continue processing the results that were 
successful. I know the Enum and Stream modules already have a lot of 
functions but I think a strain function would add significant value 
especially in overall code readability.

Here is a possible source example

def strain(enumerable) do
    Enum.reduce(enumerable, [], fn
      {:ok, tuple}, acc when is_tuple(tuple) ->
        case tuple do
          {:ok, result} -> [result | acc]
          {:error, _} -> acc
        end
      {:ok, result}, acc -> [result |  acc]
      _, acc -> acc
    end)
  end

And an overloaded version that allows for handling errors:

def strain(enumerable, fun) do
    Enum.reduce(enumerable, [], fn
      {:ok, tuple}, acc when is_tuple(tuple) ->
        case tuple do
          {:ok, result} -> [result | acc]
          {:error, result} ->
            fun.(result)
            acc
        end
      {:ok, result}, acc -> [result |  acc]
      {:error, result}, acc ->
          fun.(result)
          acc
      _, acc -> acc
    end)
  end


This would allow client code to look like this:

results = list
|> Enum.map(&do_something/1)
|> Enum.strain()
|> Task.async_stream(&do_another_expensive_thing/1)
|> Enum.strain()
|> Enum.to_list()


Simple examples (for clarity)
iex> Enum.strain([{:ok, "good job"}, {:error, "bad input"}])
["good job"]


iex> Enum.strain([{:error, "bad input"}], &IO.inspect/1)
"bad input"
[]


Thanks,
Spencer Carlson



-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/bff44726-95f0-4e71-8783-a67bfad043ef%40googlegroups.com.

Reply via email to