dialyzer-analysis

Understanding and fixing Dialyzer warnings in Erlang and Elixir code.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "dialyzer-analysis" with this command: npx skills add thebushidocollective/han/thebushidocollective-han-dialyzer-analysis

Dialyzer Analysis

Understanding and fixing Dialyzer warnings in Erlang and Elixir code.

Type Specifications

Basic Specs

@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

implementation

end

Complex Types

@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

@spec map_values(map(), (any() -> any())) :: map() @spec filter_list([t], (t -> boolean())) :: [t] when t: any()

Common Warnings

Pattern Match Coverage

Warning: pattern match is not exhaustive

case value do :ok -> :success

Missing :error case

end

Fixed

case value do :ok -> :success :error -> :failure _ -> :unknown end

No Return

Warning: function has no local return

def always_raises do raise "error" end

Fixed with spec

@spec always_raises :: no_return() def always_raises do raise "error" end

Unmatched Returns

Warning: unmatched return

def process do {:error, "failed"} # Return value not used :ok end

Fixed

def process do case do_something() do {:error, reason} -> handle_error(reason) :ok -> :ok end end

Unknown Functions

Warning: unknown function

SomeModule.undefined_function()

Fixed: ensure function exists or handle dynamically

if Code.ensure_loaded?(SomeModule) and function_exported?(SomeModule, :function_name, 1) do SomeModule.function_name(arg) end

Type Analysis Patterns

Union Types

@type result :: :ok | {:ok, any()} | {:error, String.t()}

@spec handle_result(result()) :: any() def handle_result(:ok), do: nil def handle_result({:ok, value}), do: value def handle_result({:error, msg}), do: Logger.error(msg)

Opaque Types

@opaque internal_state :: %{data: map(), timestamp: integer()}

@spec new() :: internal_state() def new, do: %{data: %{}, timestamp: System.system_time()}

Remote Types

@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

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

mix dialyzer --format dialyzer

Explain Warnings

mix dialyzer --explain

Check Specific Files

mix dialyzer lib/my_module.ex

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

typescript-type-system

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

typescript-async-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

cpp-templates-metaprogramming

No summary provided by upstream source.

Repository SourceNeeds Review