[erlang-questions] Dialyzer questions

Kostis Sagonas kostis@REDACTED
Wed May 4 08:18:37 CEST 2011


Prashanth Mundkur wrote:
> Yes, this was very helpful, thanks!  One issue I forgot to ask about was the
> following:
> 
> $ cat /tmp/dial.erl 
> -module(dial).
> -export([f/1]).
> 
> -type t() :: 'a' | 'b'.
> -spec f(atom()) -> t().
> 
> f(x) ->
>     g();
> f(y) ->
>     h().
> 
> -spec g() -> t().
> g() -> a.
> 
> -spec h() -> t().
> h() -> b.
> 
> $ dialyzer /tmp/dial.erl 
> dial.erl:12: The specification for dial:g/0 states that the function
>   might also return 'b' but the inferred return is 'a'
> dial.erl:15: The specification for dial:h/0 states that the function
>   might also return 'a' but the inferred return is 'b'
> 
> This seems like a common problem when we use helper functions and
> don't want to separately type the return values of each of the
> helpers.  Both -Wunderspecs and -Woverspecs don't help here.  Is there
> an idiomatic way of avoiding this warning, other than omitting the
> -specs for the helpers altogether?

The short answer is NO.

In simple cases like yours, I cannot see why you would not spec them as 
follows:

-type a() :: a.
-type b() :: b.
-type t() :: a() | b().

-spec f(atom()) -> t().

-spec g() -> a().

-spec h() -> b().

Seems to me that this is exactly what the | operator in types is about.

Now, of course if the code is more complicated than your example and the 
return types for the two helpers are not disjoint, then I can see the 
problem.  In such cases, if the functions are module local, I suggest 
that you simply don't spec them.

Kostis



More information about the erlang-questions mailing list