Does it really matter what the structure of the tuple is as long as the 
first item is either :ok or :error?

I usually start with that exact line, " |> Enum.filter(&match?(&1, {:ok, 
_}))", but eventually end up building a utility function because it happens 
so frequently.... my thought was that handling this in a pipe was rote, but 
if it is not so common, then I agree we should keep it out of the std lib.  

On Tuesday, August 20, 2019 at 9:53:01 PM UTC-6, Chris McCord wrote:
>
> While {:ok, result} | {:error, reason} is ubiquitous, it isn’t always so 
> strict, and the :ok and :error tuples often deviate in length for added 
> information, such as Ecto multi results. I think the existing filters work 
> quite well, so I wouldn’t add it to std lib:
>
>   |> Enum.filter(res -> match?(res, {:ok, _}) end)
>
>   # or 
>
>   |> Enum.filter(&match?(&1, {:ok, _}))
>
>
> Chris
>
>
> On Aug 20, 2019, at 10:21 PM, Spencer Carlson <[email protected] 
> <javascript:>> wrote:
>
> 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 [email protected] <javascript:>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/bff44726-95f0-4e71-8783-a67bfad043ef%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/bff44726-95f0-4e71-8783-a67bfad043ef%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
>
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/ebfdde83-78ac-4de6-9642-b8756a81df70%40googlegroups.com.

Reply via email to