The canonical way to do what you’re after is to pattern match rather than use a guard. And as you’ve indentified, you can’t pattern match in guards. Using your example:
defmodule Mondo.Util do
def precise_exchange_rate(%Decimal{} = qty, %Decimal{} = subtotal) do
if(Decimal.eq?(qty, 0), do: nil, else: Decimal.div(subtotal, qty))
end
def precise_exchange_rate(qty, subtotal) when is_binary(qty) and is_binary(subtotal) do
decimal_qty = if qty == "", do: 0, else: Decimal.new(qty)
decimal_subtotal = if subtotal == "", do: 0, else: Decimal.new(subtotal)
if(Decimal.eq?(qty, 0), do: nil, else: Decimal.div(decimal_subtotal, decimal_qty))
end
end
I also suggest you use is_binary/1
rather than is_bitstring/1
since strings in Elixir are binaries (divisible by 8) whereas bit strings can be any number of bits.