mattfara50
How would you accumulate errors?
In “Elixir in Action”, there is an example about using pattern matching with the “with” special form:
with
{:ok, login} <- extract_login(user),
{:ok, email} <- extract_mail(user),
{:ok, pw} <- extract_pw(user)
do
{:ok, %{login: login, email: email, pw: pw}}
end
If each validation of user is successful, the “ok” tuple is returned. Otherwise, the first failing validation’s “error” tuple is returned.
But suppose I wanted to run all the validations, returning the same “ok” if they all pass, but returning a list of all the “error” tuples for all failing validations.
Is there an idiom for this in Elixir? afaik this is like an applicative functor.
Marked As Solved
eksperimental
you can use
for {key, validate_fun} <- validation, reduce: [] do
acc ->
....
end
Also Liked
kokolegorille
You could reduce each function call… then check if Enum.all?, Enum.any?, whatever tests You may want to run on the list.
# NOT TESTED!
result = ~w(extract_login extract_mail extract_pw)a
|> Enum.reduce(&apply(__MODULE__, &1, [user]))
But your code looks like a user validation, and usually this can be done with a changeset.
eksperimental
Something like this, (I haven’t run the code though)
validations = [
login: &extract_login/1,
mail: &extract_mail/1,
pw: &extract_pw/1
]
Enum.reduce(validatations, [], fn {key, validate_fun}, acc ->
case validate_fun.(user) do
{:ok, value} ->
[{:ok, key, value} | acc]
:error ->
[{:error, key} | acc]
end
end)
|> Enum.reverse()
mattfara50
This looks like what I was doing in Java, where functional programming idioms are at last available. I was hoping there were a macro or special form like with that might accomplish what that reduce is doing there. I’m still learning the bare basics. Thank you!
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









