Pascal
Pascal

Reputation: 14042

unexpected result using typer

I decided to add type definition in some of my code, and I ran Typer to get a starting point (erlang 15b02, typer 0.9.4).

I picked some results to check if every thing is fine and found this result that I don't understand:

par(true, o) -> "(";
par(true, f) -> ")";
par(_, _) -> "".

which produce the spec:

-spec par(boolean(),'f' | 'o') -> [40 | 41].

I can understand the input parameters because this function is not exported, and my code only call the function with a boolean expression as first parameter, and the atoms o or f as second one (for example par(4 > P, o) ).

But why the return list does not include the empty list? I was expecting something like [40 | 41 | []] or [40 | 41 | ""]

this code is used for printing math expressions and avoid parenthesis when the priority or operator is sufficient; for example print

3 + 4 + 5 * (6 + 7) - sin( x + 7) rather than

3 + ( 4 + (( 5 * ( 6 + 7 )) - sin(( x + 7)))).

I am sure that the code is called with false as first parameter as shown by the result of test coverage:

    15..|  par(true, o) -> "(";
    15..|  par(true, f) -> ")";
   308..|  par(_, _) -> "".

Upvotes: 3

Views: 83

Answers (1)

legoscia
legoscia

Reputation: 41658

As an Erlang type specification, [X] means "a list of zero or more elements of type X". In your case, X is 40 | 41, so "(", ")", "()()" and "" all match this type. There is no way to express a list of exactly one element as a type spec.

A list with at least one element could be specified as [X,...]. The fact that typer says [40 | 41] instead of [40 | 41,...] implies that it knows that the function can return an empty list.

Upvotes: 6

Related Questions