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

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
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
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
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
sabri
Can someone explain the settings of pool_size of Ecto in config file? and what is the recommend size? Thanks
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New

We're in Beta

About us Mission Statement