Crowdhailer

Crowdhailer

Creator of Raxx

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

NobbZ

Close… when a: var, or t :wink:

Crowdhailer

Crowdhailer

Creator of Raxx

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

peerreynders

Defining a specification

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
jeremyjh

jeremyjh

Type variables are not unified by dialyzer. In the spec @spec id(t) :: t when t: var, the t as arg and t as return may as well be different type variables entirely.

OvermindDL1

OvermindDL1

Yep. I LOVE this pattern and use it excessively at times in a large variety of languages. ^.^

Where Next?

Popular in Questions Top

stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
New
Kagamiiiii
Student & New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
clayschick
I'm trying to create a simple query to select distinct values from a column. If I only use select and distinct I get back a list of uniqu...
New

Other popular topics Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New

We're in Beta

About us Mission Statement