@@ -864,7 +864,7 @@ defmodule Module.Types.Descr do
864864  defp  list_tail_unfold ( :term ) ,  do:  @ not_non_empty_list 
865865  defp  list_tail_unfold ( other ) ,  do:  Map . delete ( other ,  :list ) 
866866
867-   defp  list_union ( dnf1 ,  dnf2 ) ,  do:  dnf1  ++  dnf2 
867+   defp  list_union ( dnf1 ,  dnf2 ) ,  do:  dnf1  ++  ( dnf2   --   dnf1 ) 
868868
869869  defp  list_intersection ( dnf1 ,  dnf2 )  do 
870870    for  { list_type1 ,  last_type1 ,  negs1 }  <-  dnf1 , 
@@ -1076,12 +1076,39 @@ defmodule Module.Types.Descr do
10761076    end 
10771077  end 
10781078
1079-   # TODO: Eliminate empty lists from the union. 
1080-   defp  list_normalize ( dnf ) ,  do:  dnf 
1081-   #   Enum.filter(dnf, fn {list_type, last_type, negs} -> 
1082-   #     not Enum.any?(negs, fn neg -> subtype?(list_type, neg) end) 
1083-   #   end) 
1084-   # end 
1079+   # Eliminate empty lists from the union, and redundant types (that are subtypes of others, 
1080+   # or that can be merged with others). 
1081+   defp  list_normalize ( dnf )  do 
1082+     Enum . reduce ( dnf ,  [ ] ,  fn  { lt ,  last ,  negs } ,  acc  -> 
1083+       if  list_literal_empty? ( lt ,  last ,  negs ) , 
1084+         do:  acc , 
1085+         else:  add_to_list_normalize ( acc ,  lt ,  last ,  negs ) 
1086+     end ) 
1087+   end 
1088+ 
1089+   defp  list_literal_empty? ( list_type ,  last_type ,  negations )  do 
1090+     empty? ( list_type )  or  empty? ( last_type )  or 
1091+       Enum . any? ( negations ,  fn  { neg_type ,  neg_last }  -> 
1092+         subtype? ( list_type ,  neg_type )  and  subtype? ( last_type ,  neg_last ) 
1093+       end ) 
1094+   end 
1095+ 
1096+   # Inserts a list type into a list of non-subtype list types. 
1097+   # If the {list_type, last_type} is a subtype of an existing type, the negs 
1098+   # are added to that type. 
1099+   # If one list member is a subtype of {list_type, last_type}, it is replaced 
1100+   # and its negations are added to the new type. 
1101+   # If the type of elements are the same, the last types are merged. 
1102+   defp  add_to_list_normalize ( [ { t ,  l ,  n }  |  rest ] ,  list ,  last ,  negs )  do 
1103+     cond  do 
1104+       subtype? ( list ,  t )  and  subtype? ( last ,  l )  ->  [ { t ,  l ,  n  ++  negs }  |  rest ] 
1105+       subtype? ( t ,  list )  and  subtype? ( l ,  last )  ->  [ { list ,  last ,  n  ++  negs }  |  rest ] 
1106+       equal? ( t ,  list )  ->  [ { t ,  union ( l ,  last ) ,  n  ++  negs }  |  rest ] 
1107+       true  ->  [ { t ,  l ,  n }  |  add_to_list_normalize ( rest ,  list ,  last ,  negs ) ] 
1108+     end 
1109+   end 
1110+ 
1111+   defp  add_to_list_normalize ( [ ] ,  list ,  last ,  negs ) ,  do:  [ { list ,  last ,  negs } ] 
10851112
10861113  ## Dynamic 
10871114  # 
0 commit comments