Crowdhailer
How to declare type variables using elixir/dialyixir?
NOTE all these questions are related to my use of dialyxir.
Type variables
From the erlang documentation.
Type variables can be used in specifications to specify relations for the input and output arguments of a function. For example, the following specification defines the type of a polymorphic identity function:
-spec id(X) -> X.
This suggests that dialyzer does support type variables and polymorphic types. I cannot see how to declare type variables in Elixir. For example I tried the following code
defmodule TypeVariables do
@spec id(T) :: T
def id(x) do
x
end
def run() do
id(:foo)
end
end
However this fails because the compiler does not consider T as a variabled. Running dialyxir gives the following output.
lib/test1.ex:7: Function run/0 has no local return
lib/test1.ex:8: The call 'Elixir.TypeVariables':id('foo') breaks the contract ('Elixir.T') -> 'Elixir.T'
Most Liked
NobbZ
Close… when a: var, or t ![]()
Crowdhailer
Does anyone do this or similar.
Here I am using a spec’d identity function to “cast” a binary to an opaque type which will instruct dialyzer to warn when I try to use it in normal strip operation.
defmodule MyID do
@opaque t(x) :: x
@spec id(binary) :: t(binary)
def id(x) do
x
end
def run do
id = id("alice")
String.upcase(id)
end
end
peerreynders
Type variables with no restriction can also be defined.
That reads as if it is simply unconstrained rather than unified.
In my experience dialyzer wants specifics, e.g.
@type my_t(t) :: list(t)
@type my_int_t :: my_t(integer())
@spec id(t) :: t when t: my_int_t
@spec id(t) :: t when t: integer()
@spec id(atom()) :: atom()
def id(x) do
x
end
@spec run() :: r when r: atom()
def run() do
id(:foo)
end
@spec run2() :: r when r: integer()
def run2() do
id(10)
end
@spec run3() :: r when r: my_int_t
def run3() do
id([10])
end
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #javascript
- #code-sync
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








