Why binary literals can’t be types so I could have something like:
-type currency() :: <<"EUR">> | <<"USD">>.
?
Is there currently a way to express this?
Why binary literals can’t be types so I could have something like:
-type currency() :: <<"EUR">> | <<"USD">>.
?
Is there currently a way to express this?
Is there currently a way to express this?
I couldn’t tell you why it is how it is, but from the docs, it looks like what you want is entirely unrepresentable:
Bitstring :: <<>>
| <<_:M>> %% M is an Integer_Value that evaluates to a positive integer
| <<_:_*N>> %% N is an Integer_Value that evaluates to a positive integer
| <<_:M, _:_*N>>
src: Types and Function Specifications — Erlang System Documentation v27.0.1
I know, but I wonder why is it like that.
I can image that could work very well with e.g. gradualizer
and parsing libraries that operate on binaries (e.g. to check that all possible cases are handled).
Here is some information regarding this “issue”: Syntax error when using binary or string as a key in a map based type specification · Issue #6202 · erlang/otp · GitHub.
This is a result of decisions made when designing the type system used by Dialyzer.
What can be represented in a type system must strike a balance between expressiveness and efficiency of operations. One can have opinions on what is “useful” and “consistent”. As another example, string literals, while allowed in -specs and -types, get flattened by Dialyzer (i.e. “success” becomes “nonempty list of $s,$u,$c,$e”), but maybe/likely not by other tools.
how do you mean string literals are allowed?
Sorry, I was wrong.
String literals like e.g. -type one() :: "one".
are also not allowed. No idea why I thought they might have been.
From Dialyzer’s perspective, there could be, since erl_types:t_from_term/1
exists, and already handles syntax such as "one"
for typing literals and patterns, and behaves as you said above. Maybe that’s what you were thinking of? I also had to double check this.