fireproofsocks
I’m confused… when grooming the docs for https://elixir-lang.org/getting-started/typespecs-and-behaviours.html I got the feedback that multiple function clauses require multiple @specs. But now that I’m digging into dialyzer, I’m getting errors in places where I’ve done that. E.g.
Overloaded contract for MyApp.some_function/1 has
overlapping domains; such contracts are currently unsupported and
are simply ignored.
Consider this module:
defmodule MyApp.Helpers do
alias Absinthe.Blueprint.Input.String, as: AbsintheString
alias Absinthe.Blueprint.Input.Integer, as: AbsintheInteger
alias Absinthe.Blueprint.Input.Float, as: AbsintheFloat
@spec parse_value(AbsintheString.t() | AbsintheInteger.t() | AbsintheFloat.t() | any()) :: {:ok, String.t()} | {:error, any()}
def parse_value(%AbsintheString{value: value}) do
{:ok, value}
end
def parse_value(%AbsintheInteger{value: value}) do
{:ok, Integer.to_string(value)}
end
def parse_value(%AbsintheFloat{value: value}) do
{:ok, Float.to_string(value)}
end
def parse_value(_) do
{:error, "Invalid value"}
end
end
Dialyzer seems happy when it has only a single combined @spec, but readability is better when each function clause has its own @spec, something more like this:
@spec parse_value(AbsintheString.t()) :: {:ok, String.t()}
def parse_value(%AbsintheString{value: value}) do
{:ok, value}
end
@spec parse_value(AbsintheInteger.t()) :: {:ok, String.t()}
def parse_value(%AbsintheInteger{value: value}) do
{:ok, Integer.to_string(value)}
end
# ... etc...
Which way is correct?
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex










Showing Posts 1 to 6- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
NobbZ
Both are correct.
Use whichever you prefer, though having multiple specs can lead to “overlapping” specs, which are not allowed.
Also
... | ... | anycan be simplified toany.Last but not least, dialyzer will combine the second version into the first anyway.
fireproofsocks
What exactly are “overlapping specs”?
ityonemo
In the example you gave the two typepecs are quite literally identical, so the preimage and range of both “functions” trivially overlaps. Here’s a nonoverlapping typespec with associated function:
I prefer to group my typespecs for distinct function entry points (this is rare) together, and I personally organize spec, doc, function bodies. But these are stylistic choices.
fireproofsocks
AbsintheStringandAbsintheInteger(or any disparate structs) are identical?ityonemo
whoops, that detail missed me.
michallepicki
You’re only getting this warning because of the fallback function clause with
any. If types for all function arguments overlap, Dialyzer will show a warning (not an error AFAIK) and (I think?) it will use only the last version.Multiple specs are sometimes useful when you can have different argument types and maybe different return types for them. Separate
@speccan look cleaner than a big one with many| ... | ....But if specs are the same (or overlapping) I would probably use just one. Notice what
ex_docgenerates for the same specs: it will just list the same thing multiple times.