I did my experiment by copy and paste:
defmodule MyDecimal do
# `to_integer/1` is copied from the source code of `Decimal`,
# and added some `IO.inspect`
def to_integer(%Decimal{sign: sign, coef: coef, exp: 0} = d)
when is_integer(coef) do
IO.inspect(d, label: "Branch 1", structs: false)
sign * coef
end
def to_integer(%Decimal{sign: sign, coef: coef, exp: exp} = d)
when is_integer(coef) and exp > 0 do
IO.inspect(d, label: "Branch 2", structs: false)
to_integer(%Decimal{sign: sign, coef: coef * 10, exp: exp - 1})
end
def to_integer(%Decimal{sign: sign, coef: coef, exp: exp} = d)
when is_integer(coef) and exp < 0 and Kernel.rem(coef, 10) == 0 do
IO.inspect(d, label: "Branch 3", structs: false)
to_integer(%Decimal{sign: sign, coef: Kernel.div(coef, 10), exp: exp + 1})
end
end
MyDecimal.to_integer(Decimal.new("1234.50"))
and it prints
Branch 3: %{__struct__: Decimal, coef: 123450, exp: -2, sign: 1}
** (FunctionClauseError) no function clause matching in MyDecimal.to_integer/1
The following arguments were given to MyDecimal.to_integer/1:
# 1
#Decimal<1234.5>
#cell:2: MyDecimal.to_integer/1
So, the “problem” occurs when trying to do to_integer(%Decimal{sign: 1, coef: 12345, exp: -1}).
Maybe Decimal does not want you to do anything ambiguous about the fraction part.


















