<< All versions
Skill v1.0.1
currentAutomated scan100/100thebushidocollective/han/dialyzer-analysis
4 files
──Details
PublishedSeptember 28, 2026 at 08:57 PM
Content Hashsha256:43f8067f7275bf0b...
Git SHA19caa51d5fd1
Bump Typepatch
──Files
Files (1 file, 3.3 KB)
SKILL.md3.3 KBactive
SKILL.md · 187 lines · 3.3 KB
version: "1.0.1" name: dialyzer-analysis user-invocable: false description: Use when analyzing and fixing Dialyzer warnings and type discrepancies in Erlang/Elixir code. allowed-tools: []
Dialyzer Analysis
Understanding and fixing Dialyzer warnings in Erlang and Elixir code.
Type Specifications
Basic Specs
elixir
@spec add(integer(), integer()) :: integer()def add(a, b), do: a + b@spec get_user(pos_integer()) :: {:ok, User.t()} | {:error, atom()}def get_user(id) do# implementationend
Complex Types
elixir
@type user :: %{id: pos_integer(),name: String.t(),email: String.t(),role: :admin | :user | :guest}@spec process_users([user()]) :: {:ok, [user()]} | {:error, String.t()}
Generic Types
elixir
@spec map_values(map(), (any() -> any())) :: map()@spec filter_list([t], (t -> boolean())) :: [t] when t: any()
Common Warnings
Pattern Match Coverage
elixir
# Warning: pattern match is not exhaustivecase value do:ok -> :success# Missing :error caseend# Fixedcase value do:ok -> :success:error -> :failure_ -> :unknownend
No Return
elixir
# Warning: function has no local returndef always_raises doraise "error"end# Fixed with spec@spec always_raises :: no_return()def always_raises doraise "error"end
Unmatched Returns
elixir
# Warning: unmatched returndef process do{:error, "failed"} # Return value not used:okend# Fixeddef process docase do_something() do{:error, reason} -> handle_error(reason):ok -> :okendend
Unknown Functions
elixir
# Warning: unknown functionSomeModule.undefined_function()# Fixed: ensure function exists or handle dynamicallyif Code.ensure_loaded?(SomeModule) andfunction_exported?(SomeModule, :function_name, 1) doSomeModule.function_name(arg)end
Type Analysis Patterns
Union Types
elixir
@type result :: :ok | {:ok, any()} | {:error, String.t()}@spec handle_result(result()) :: any()def handle_result(:ok), do: nildef handle_result({:ok, value}), do: valuedef handle_result({:error, msg}), do: Logger.error(msg)
Opaque Types
elixir
@opaque internal_state :: %{data: map(), timestamp: integer()}@spec new() :: internal_state()def new, do: %{data: %{}, timestamp: System.system_time()}
Remote Types
elixir
@spec process_conn(Plug.Conn.t()) :: Plug.Conn.t()@spec format_date(Date.t()) :: String.t()
Success Typing
Dialyzer uses success typing:
- Approximates what a function can succeed with
- Different from traditional type systems
- May miss some errors, but no false positives (in theory)
Example
elixir
# Dialyzer infers: integer() -> integer()def double(x), do: x * 2# More specific spec@spec double(pos_integer()) :: pos_integer()def double(x) when x > 0, do: x * 2
Best Practices
- Start with Core Modules: Add specs to public APIs first
- Use Strict Types: Prefer specific types over
any() - Document Assumptions: Use specs to document expected behavior
- Test Specs: Ensure specs match actual behavior
- Iterative Fixing: Fix warnings incrementally
Debugging Tips
Verbose Output
bash
mix dialyzer --format dialyzer
Explain Warnings
bash
mix dialyzer --explain
Check Specific Files
bash
mix dialyzer lib/my_module.ex