<div dir="ltr">Thanks a lot Craig  <div>Amazing , detailed information . However I do feel there is an inconsistency in the behavior of erlang compiler vs dialyzer. </div><div>Inconsistencies</div><div>=============</div><div>1. Although a type-spec doesn't allow you to specify a  "set" of objects, it lets us specify a set of integers e.g 0..12  etc.</div><div>2. You can specify definitions as bitstring() or string()  instead of a set of values, but dialyzer complains that the return type </div><div>     is a super-type of the set of values being returned . </div><div><br></div><div>Erlang has a powerful pattern matcher, hence potentially we can afford to return sets of arbitrary unique objects from functions ,</div><div>hence we do need the ability to specify a unique set of any data-type , e.g strings, bitstrings, tuples .</div><div>just my opinion, thanks again for the help!.</div><div>Regards</div><div>sachin</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 17, 2016 at 10:52 PM, zxq9 <span dir="ltr"><<a href="mailto:zxq9@zxq9.com" target="_blank">zxq9@zxq9.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 2016年3月17日 木曜日 21:53:06 Sachin Panemangalore wrote:<br>
> 1. The following compiles fine in Erlang.<br>
><br>
</span>> -define(MY_INT_MACRO1, 1).<br>
> -define(MY_INT_MACRO2, 2).<br>
> -type my_type() :: ?MY_INT_MACRO1 |  ?MY_INT_MACRO2 .<br>
<span class="">><br>
><br>
> 2. The following doesn't<br>
><br>
</span>> -define(MY_BITSTRING_MACRO1, <<"01">>).<br>
> -define(MY_BITSTRING_MACRO2, <<"02">>).<br>
<span class="">> -type my_type() :: ?MY_BITSTRING_MACRO1 |  ?MY_BITSTRING_ MACRO2 .<br>
><br>
> Why ? and is there a way to make this work ?<br>
<br>
</span>(Changed the names above to say what I think you meant.)<br>
<br>
Type declarations have a few limitations with regard to defining what is<br>
inside. You can declare the size of a binary, but not what it contains,<br>
hence these sort of type definitions:<br>
<a href="https://github.com/zxq9/zuuid/blob/master/src/zuuid.erl#L47-L56" rel="noreferrer" target="_blank">https://github.com/zxq9/zuuid/blob/master/src/zuuid.erl#L47-L56</a><br>
<br>
In the same way, you can declare a dictionary or map's k/v types:<br>
<br>
-type my_dict() :: dict:dict(atom(), integer()).<br>
-type my_map()  :: maps:map(atom(), string()).<br>
<br>
You'll never be able to provide a complete, fixed shape of a dict or<br>
map, though, because that would actually be a schema, and that's what<br>
using tuple or records as types already does. This only turns out to<br>
be the same limitation as we have defining lists of things:<br>
<br>
-type my_tuple_list() :: [{atom(), some_type()}].<br>
<br>
This is why the following is not legal:<br>
<br>
-type some_phrase() :: "I am a string literal.".<br>
<br>
Actually, I think you can't even declare a list of some specific length,<br>
which leaves binary type definitions slightly more rigorous than lists. But<br>
if you *knew* the length of a list why wouldn't you be using a tuple?<br>
<br>
It would be pretty convenient to be able to define types based on binary<br>
literals, since their use case differs from binaries. But on the other hand,<br>
if you want binary strings defined this way you usually actually want atoms<br>
that you can derive from some external binary data you receive -- and atoms<br>
are (usually) an excellent way to clean up your type defs in<br>
self-documenting ways.<br>
<br>
-Craig<br>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div><br></div>