case is_email_address?(email) do
true ->
case String.length(code) == 6 do
true ->
case EmailConfirmations.get_email_confirmation(email) do
%EmailConfirmation{} ->
case EmailAddresses.get_email_address(email) do
nil ->
case Users.create_user(data) do
{:ok, user} ->
case EmailAddresses.create_email_address(user, email) do
{:ok, email_address} ->
# success block
fail -> fail
end
fail -> fail
end
fail -> fail
end
fail -> fail
end
fail -> fail
end
fail ->
case fail do
# else conditions
end
end
Elixir will be able to do something closer to `case` exhaustiveness checking with the gradual typing being built, and dialyzer can sort of perform exhaustiveness checking as long as your type specs are written well enough. (I’ve observed two things about `with` statements in Elixir: they should have more than one condition clause, or they should be written as `case` statements; they should not have an `else` clause, as that suggests that error path normalization isn't happening at the right level.)In many ways what's described is much closer to `cond`, except that `cond` is completely open ended except for the required `true` clause, which means that there is absolutely no exhaustiveness checking.
I'll admit that I mostly skimmed this and I don't use ML or Haskell, but I couldn't see what benefit this provides over Elixir's `case` or Rust's `match` (recognizing that the former can't do exhaustiveness checking as yet, but `match` absolutely can).