defmodule Lima do
@type unit_quantity_t :: 0..1000
@type unit_quantity_error :: {:error, String.t()}
@type unit_quantity_success :: {:ok, unit_quantity_t()}
@type unit_quantity_result :: unit_quantity_success() | unit_quantity_error()
@spec create_unit_quantity_error(s) :: r when s: String.t, r: unit_quantity_error()
defp create_unit_quantity_error(msg),
do: {:error, msg}
@spec create_unit_quantity_success(n) :: r when n: unit_quantity_t(), r: unit_quantity_success()
defp create_unit_quantity_success(qty),
do: {:okidoki, qty}
@spec create_unit_quantity(n) :: r when n: integer(), r: unit_quantity_result()
def create_unit_quantity(qty) when is_integer(qty) do
cond do
qty < 0 ->
create_unit_quantity_error("unit_quantity can not be negative")
qty > 1_000 ->
create_unit_quantity_error("unit_quantity can not be more than 1000")
true ->
create_unit_quantity_success(qty)
end
end
end
.
$ mix dialyzer
...
Compiling 1 file (.ex)
Checking PLT...
[:compiler, :elixir, :kernel, :logger, :stdlib]
PLT is up to date!
Starting Dialyzer
dialyzer args: [check_plt: false,
init_plt: '/Users/wheatley/sbox/elx/trial/lima/_build/dev/dialyxir_erlang-19.3_elixir-1.4.4_deps-dev.plt',
files_rec: ['/Users/wheatley/sbox/elx/trial/lima/_build/dev/lib/lima/ebin'],
warnings: [:unknown]]
done in 0m1.34s
lib/lima.ex:11: Invalid type specification for function 'Elixir.Lima':create_unit_quantity_success/1. The success typing is (integer()) -> {'okidoki',integer()}
done (warnings were emitted)
$
Alternately
defmodule Lima do
@type result_error_t :: {:error, String.t()}
@type result_success_t(t) :: {:ok, t}
@type result_t(t) :: result_success_t(t) | result_error_t()
@type unit_quantity_t :: 0..1000
@spec unit_quantity_error(s) :: r when s: String.t, r: result_error_t()
defp unit_quantity_error(msg),
do: {:error, msg}
@spec unit_quantity_success(v) :: r when v: unit_quantity_t(), r: result_success_t(unit_quantity_t())
defp unit_quantity_success(qty),
do: {:ok, qty}
@spec create_unit_quantity(n) :: r when n: integer(), r: result_t(unit_quantity_t())
def create_unit_quantity(qty) when is_integer(qty) do
cond do
qty < 0 ->
unit_quantity_error("unit_quantity can not be negative")
qty > 1_000 ->
unit_quantity_error("unit_quantity can not be more than 1000")
true ->
unit_quantity_success(qty)
end
end
end