I’ve created a macro operator ~> that injects a case that will bypass the right statement if the left is :error or { :error, _ }, and pipeline to the right otherwise. It’s a conditional |> pipe operator.
The problem is that dialyzer complains that “The pattern can never match the type” because not all functions can produce both kinds of error values. Such as:
lib/dc_example.ex:16:pattern_match
The pattern can never match the type.
Pattern:
:error
Type:
<<_::64, _::size(8)>>
In this instance, it can return a string or an error tuple, but not a bare :error.
For clarity, dialyzer is doing the right thing from an analysis standpoint. Is there a way that I can provide dialyzer with a hint or exclusion that won’t disable pattern match checks?
Here is a working example:
defmodule DcExample do
defmacro left ~> right do
quote do
case unquote( left ) do
{ :error, _ } = err -> err
:error -> :error
val ->
unquote( Macro.pipe( (quote do: val), right, 0 ) )
end
end
end
def hello( it ) do
good( it )
~> bad
|> IO.inspect
end
def good(it) do
case :crypto.rand_uniform(1,10) > 5 do
true -> "(#{it}) alls well"
false -> { :error, :oops }
end
end
def bad( arg ) do
case :crypto.rand_uniform(1,10) > 5 do
true -> :error
false -> "input plus " <> arg
end
end
def run do
Enum.each(1..10, &hello/1)
end
end
I don’t “think” it does sadly… @dyalizer attributes is always what I’ve had to do (unless I can hoist it to another function call), but I’m hoping someone responds with a better suggestion here. ^.^;
I have been having a similar problem to the one described in this post, but I can’t find any usage documentation about the @dyalizer attribute or setting generated: true.
What are these two options? what do they mean? Are there any resources where I can read about them?
@neenjaw I don’t see generated: true option for the @dialyzer module attribute documented in either of these documents, did you find it anywhere? I only found some code in elixir that uses it as an option for quote, tested here and documented here
I couldn’t find anything specific, but read that @dialyzer takes atom, tuples. So given the conversation above I just put it at the top of my file that was generating the error and it went away.
When I comment out the line, the error comes back.
The error I was specifically trying to suppress was being thrown by a macro to create a function with branching logic based on a specified module attributes. So I would get a true =:= false, true can never equal false warning.