dogweather
Is this a good pattern for handling a list of {:ok|:error} results?
I’m parsing input, returning the successfully parsing items, and logging the parse errors. (In this app, this is the behavior I want: continue working with successful parses, and a log file with the errata.)
processed_sections = map(raw_sections, &new_section/1)
reduce(processed_sections, [], fn e, acc ->
case e do
{:error, msg} ->
Logger.warn(msg)
acc
{:ok, section} ->
acc ++ [section]
end
end)
Is there some more canonical way of working through the {:ok|:error} results?
Most Liked
Sorc96
I tend to prefer functions other than custom reduce, so in this case, I would probably do someting like this:
{successful, failed} = Enum.split_with(processed_sections, &match?({:ok, _}, &1))
Enum.each(failed, fn {:error, msg} -> Logger.warn(msg) end)
successful
Seriously though, we need a standardized higher level way to work with :ok and :error tuples.
100phlecs
You can get rid of the case statement with anonymous function pattern matching:
i.e.
[{1, 2}, {3}, {4, 5}]
|> Enum.reduce(0, fn
{x, y}, acc -> acc + x + y
{x}, acc -> acc + x
end)
or in your case
processed_sections = map(raw_sections, &new_section/1)
reduce(processed_sections, [], fn
{:error, msg}, acc ->
Logger.warn(msg)
acc
{:ok, section}, acc ->
acc ++ [section]
end)
al2o3cr
This can be golfed down even further by using Enum.flat_map to express the “map, but only keep some of them” idiom:
raw_sections
|> map(&new_section/1)
|> Enum.flat_map(fn
{:ok, result} -> [result]
{:error, msg} -> Logger.warn(msg); []
end)
Monad enthusiasts should be able to spot Result being transformed into Option there ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









