Crowdhailer
Creator of Raxx
Help with dialyzer warning on typespec that includes anonymous function
I have the following small bind (or flat_map) implementation for error tuples.
@spec bind({:ok, a} | {:error, reason}, function(a) :: {:ok, b} | {:error, reason}) ::
{:ok, b} | {:error, reason}
when a: any, b: any, reason: term
def bind({:ok, value}, func) when is_function(func, 1), do: func.(value)
def bind({:error, reason}, _func), do: {:error, reason}
When I use this function as follows
@spec safe_div(integer, integer) :: {:ok, float} | {:error, :zero_division}
def safe_div(_, 0) do
{:error, :zero_division}
end
def safe_div(a, b) do
{:ok, a / b}
end
OK.bind({:ok, 4}, &safe_div(3, &1))
I see the following warning.
test/integration.ex:5:no_return
Function run/0 has no local return.
________________________________________________________________________________
Please file a bug in https://github.com/jeremyjh/dialyxir/issues with this message.
Failed to parse warning:
[{:"(", 1}, {:"{", 1}, {:atom_full, 1, '\'ok\''}, {:",", 1}, {:atom_part, 1, 'a'}, {:"}", 1}, {:|, 1}, {:"{", 1}, {:atom_full, 1, '\'error\''}, {:",", 1}, {:atom_part, 1, 'r'}, {:atom_part, 1, 'e'}, {:atom_part, 1, 'a'}, {:atom_part, 1, 's'}, {:atom_part, 1, 'o'}, {:atom_part, 1, 'n'}, {:"}", 1}, {:",", 1}, {:atom_part, 1, 'f'}, {:atom_part, 1, 'u'}, {:atom_part, 1, 'n'}, {:atom_part, 1, 'c'}, {:atom_part, 1, 't'}, {:atom_part, 1, 'i'}, {:atom_part, 1, 'o'}, {:atom_part, 1, 'n'}, {:"(", 1}, {:atom_part, 1, 'a'}, {:")", 1}, {:::, 1}, {:"{", 1}, {:atom_full, 1, '\'ok\''}, {:",", 1}, {:atom_part, 1, 'b'}, {:"}", 1}, {:|, 1}, {:"{", 1}, {:atom_full, 1, '\'error\''}, {:",", 1}, {:atom_part, 1, 'r'}, {:atom_part, 1, 'e'}, {:atom_part, 1, 'a'}, {:atom_part, 1, 's'}, {:atom_part, 1, 'o'}, {:atom_part, 1, 'n'}, {:"}", 1}, {:")", 1}, {:->, 1}, {:"{", ...}, {...}, ...]
Legacy warning:
test/integration.ex:12: The call 'Elixir.OK':bind({'ok', 4},fun((_) -> {'error','zero_division'} | {'ok',float()})) breaks the contract ({'ok',a} | {'error',reason},function(a)::{'ok',b} | {'error',reason}) -> {'ok',b} | {'error',reason} when a :: any(), b :: any(), reason :: term()
________________________________________________________________________________
test/integration.ex:42:unused_fun
Function fetch_key/2 will never be called.
________________________________________________________________________________
done (warnings were emitted)
I can’t make head or tail of it. Any help would be appreciated.
You can see the full code on this PR. https://github.com/CrowdHailer/OK/pull/54
Most Liked
sasajuric
Author of Elixir In Action
To specify a lambda, you should use (arg1, arg2, ... -> result). With that change, the following typespec should be working:
@spec bind({:ok, a} | {:error, reason}, (a -> {:ok, b} | {:error, reason})) ::
{:ok, b} | {:error, reason}
when a: any, b: any, reason: term
3
NobbZ
Because you create a parameter named function(a) which shall have the type b, which again is an alias for any. And there is no value that contradicts any.
2
Popular in Questions
What is the proper way to load a module from a file in to IEX?
In the python world, doing something like this pretty standard:
from ....
New
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
Hello all!
I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Hi,
is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
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
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible.
total = 10
while total != 0
...
New
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
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
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
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
Other popular topics
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
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
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
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
I have a User schema with a :from_id field set to type :string:
defmodule TweetBot.Repo.Migrations.CreateUsers do
use Ecto.Migration
...
New
Hi everyone,
One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
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







