I have two functions, I want to run step_1
, then run step_2
only if step_1
was ok. Whats the most functionally idiomatic way to structure this code? Nesting case
statements seems ugly but I'm not sure how else to do it besides an if
which is even worse.
defmodule Test do
def step_1 do
IO.puts "Step 1"
:error
end
def step_2 do
IO.puts "Step 2"
:ok
end
def do_something_case do
case step_1 do
:ok ->
case step_2 do
:ok -> {:ok}
:error -> {:error, :step_2}
end
:error -> {:error, :step_1}
end
end
def do_something_if do
r1 = step_1
if r1 == :ok
r2 = step_2
if r2 == :ok
:ok
else
{:error, :step_2}
end
else
{:error, :step_1}
end
end
end
A common way to solve this problem (without a monad library) is to pattern match on the arguments of the functions and pipe them together.
defmodule Test do
def step_1 do
IO.puts "Step 1"
:error
end
def step_2(:ok) do
IO.puts "Step 2"
:ok
end
def step_2({:error, _reason} = error) do
error
end
def do_something_pipeline do
step_1
|> step_2
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With