[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