I am reading with interest the online book "learn you some erlang" and trying some exercises to check my understanding.
I made some modification on the fifo example, in the chapter Type Specifications and Erlang, trying to define a "typed_fifo(T)" (a fifo where all elements must be of the same type T)
my type specification are:
-type typed_empty_fifo() :: {fifo, [], []}.
-type typed_nonempty_fifo(A) :: {fifo, nonempty_list(A), list(A)} | {fifo, [],nonempty_list(A) }.
-type typed_fifo(A) :: typed_empty_fifo() | typed_nonempty_fifo(A).
and when I use it in the following function spec:
-spec empty (typed_empty_fifo()) -> true;
(typed_nonempty_fifo(_)) -> false.
empty({fifo, [], []}) -> true;
empty({fifo, A, B}) when is_list(A), is_list(B) -> false.
Dialyzer tells that it will ignore the specification because of overlapping domain.
Can somebody tells me where I make a mistake?
I have another point, before trying to define typed fifo I had a version that worked nicely, An Dialyzer show me that nothing prevent the usage of improper lists. Surprizingly, I do not find a simple way (that I can use in a guard) to test for proper/improper character of a list.
It is really strange, because when I use the bif length/1, it is able to fail with the reason badarg!
23> L=[1,2|3]. ==> [1,2|3]
24> is_list(L). ==> true
25> length(L). ==> exception error: bad argument
in function length/1 called as length([1,2|3])
Thanks