Pattern matching functions and dialyzer

The issue is that it is a single function - the fact that it is split into multiple clauses is an implementation detail that has nothing to do with the function’s actual type. So if you want tighter typing you need to define separate functions with separate types - but the moment you delegate from the multi-clause function to the specific functions you lose the direct correlation between the input types and the output types on the multi-clause function - because you are creating the respective sum (or union) types for those inputs and outputs. Try as you might:

@spec validate_generator(any) :: :ok | {:error, String.t}

is the effective type of that function. What you are trying to do is tie a specific type to part of a function’s implementation - functions and types simply don’t work that way.

This is one of the reasons why I’ve come around to seeing the mainstream way of typing:

function_name(parameter_name : parameter_type) : return_type

as conflating types with implementation - as in many cases the parameter names are coupled to the implementation. I find myself often in the situation where I know the type of the function before I have good names for all the parameters (and perhaps even the function).

It’s usually helpful to write down the type of new functions first;