Reputation: 14042
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
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