Thu Jul 27 13:39:52 EDT 2017

atom() vs. atom list

my -spec contract says e.g. a|b but dialyzer infers it as atom().
What is causing this?

I suspect this has to do with the number of cases.  If I remove one,
it infers correctly as a sum of atoms.

Indeed. This is inferred as atom() -> ok.


test(X) ->
    case X of
        a -> ok;
        b -> ok;
        c -> ok;
        d -> ok;
        e -> ok;
        f -> ok;
        g -> ok;
        h -> ok;
        i -> ok;
        j -> ok;
        k -> ok;
        l -> ok;

        m -> ok;  %% comment this out and it infers a sum of individual atoms instead of atom()

        %% n -> ok;
        %% o -> ok;
        %% p -> ok;
        %% q -> ok;
        %% r -> ok;
        %% s -> ok;
        %% t -> ok;
        %% u -> ok;
        %% v -> ok;
        %% w -> ok;
        %% x -> ok;
        %% y -> ok;
        z -> ok

I guess the idea is : don't have this many cases...  If this pattern
shows up it's likely better to make a module that has the functions as

I'd like to know why though.  This smells like an aribtrary limit in
the definition of Erlang's success typing that is introduced to avoid
combinatorial explosion.  It should be documented somewhere.