View Source Without (Without v0.1.0)
Without
is a tiny module to ease the usage of result tuple.
Using case
once is convenient, using it more than twice, makes the code less readable, consider this snippet
case find_user(email) do
{:ok, user} ->
case find_friends(user) do
{:ok, friends} -> "#{user} is friends of #{Enum.join(",", friends)}"
{:error, :friends_not_found} -> "#{user} doesn't have any friends"
end
{:error, :user_not_found} -> "user not found"
end
You might ask maybe with
could help on that?
with {:ok, user} <- find_user(email),
{:ok, friends} <- find_friends(user) do
"#{user} is friends of #{Enum.join(",", friends)}"
else
{:error, :user_not_found} -> "user not found"
{:error, :friends_not_found} -> "#{user} doesn't have any friends"
end
But the issue here is that variable user
is not available in the last else case!
Now that you feel the pain, let me introduce you to Without
!
email
|> Without.fmap_ok(&find_user/1, assign: :user)
|> Without.fmap_ok(&find_friends/1)
|> Without.fmap_error(fn error, assigns ->
case error do
:user_not_found -> "user not found"
:friends_not_found, assigns -> "#{assigns[:user]} doesn't have any friends"
end)
|> Without.fresult
If you are a functional programming aficionado, it might resemble monadic error handling.