@@ -91,53 +91,59 @@ defmodule Module.Types.Of do
9191 Builds a closed map.
9292 """
9393 def closed_map ( pairs , extra \\ [ ] , stack , context , of_fun ) do
94- result =
95- reduce_ok ( pairs , { true , extra , [ ] , context } , fn
94+ of_fun = fn arg1 , arg2 , arg3 ->
95+ case of_fun . ( arg1 , arg2 , arg3 ) do
96+ { :ok , type , context } -> { type , context }
97+ { :error , context } -> { dynamic ( ) , context }
98+ { type , context } -> { type , context }
99+ end
100+ end
101+
102+ { closed? , single , multiple , context } =
103+ Enum . reduce ( pairs , { true , extra , [ ] , context } , fn
96104 { key , value } , { closed? , single , multiple , context } ->
97- with { :ok , keys , context } <- of_finite_key_type ( key , stack , context , of_fun ) ,
98- { :ok , value_type , context } <- of_fun . ( value , stack , context ) do
99- case keys do
100- :none ->
101- { :ok , { false , single , multiple , context } }
102-
103- [ key ] when multiple == [ ] ->
104- { :ok , { closed? , [ { key , value_type } | single ] , multiple , context } }
105-
106- keys ->
107- { :ok , { closed? , single , [ { keys , value_type } | multiple ] , context } }
108- end
105+ { keys , context } = of_finite_key_type ( key , stack , context , of_fun )
106+ { value_type , context } = of_fun . ( value , stack , context )
107+
108+ case keys do
109+ :none ->
110+ { false , single , multiple , context }
111+
112+ [ key ] when multiple == [ ] ->
113+ { closed? , [ { key , value_type } | single ] , multiple , context }
114+
115+ keys ->
116+ { closed? , single , [ { keys , value_type } | multiple ] , context }
109117 end
110118 end )
111119
112- with { :ok , { closed? , single , multiple , context } } <- result do
113- map =
114- case Enum . reverse ( multiple ) do
115- [ ] ->
116- pairs = Enum . reverse ( single )
117- if closed? , do: closed_map ( pairs ) , else: open_map ( pairs )
120+ map =
121+ case Enum . reverse ( multiple ) do
122+ [ ] ->
123+ pairs = Enum . reverse ( single )
124+ if closed? , do: closed_map ( pairs ) , else: open_map ( pairs )
118125
119- [ { keys , type } | tail ] ->
120- for key <- keys , t <- cartesian_map ( tail ) do
121- pairs = Enum . reverse ( single , [ { key , type } | t ] )
122- if closed? , do: closed_map ( pairs ) , else: open_map ( pairs )
123- end
124- |> Enum . reduce ( & union / 2 )
125- end
126+ [ { keys , type } | tail ] ->
127+ for key <- keys , t <- cartesian_map ( tail ) do
128+ pairs = Enum . reverse ( single , [ { key , type } | t ] )
129+ if closed? , do: closed_map ( pairs ) , else: open_map ( pairs )
130+ end
131+ |> Enum . reduce ( & union / 2 )
132+ end
126133
127- { :ok , map , context }
128- end
134+ { map , context }
129135 end
130136
131137 defp of_finite_key_type ( key , _stack , context , _of_fun ) when is_atom ( key ) do
132- { :ok , [ key ] , context }
138+ { [ key ] , context }
133139 end
134140
135141 defp of_finite_key_type ( key , stack , context , of_fun ) do
136- with { :ok , key_type , context } <- of_fun . ( key , stack , context ) do
137- case atom_fetch ( key_type ) do
138- { :finite , list } -> { :ok , list , context }
139- _ -> { :ok , :none , context }
140- end
142+ { key_type , context } = of_fun . ( key , stack , context )
143+
144+ case atom_fetch ( key_type ) do
145+ { :finite , list } -> { list , context }
146+ _ -> { :none , context }
141147 end
142148 end
143149
@@ -156,15 +162,22 @@ defmodule Module.Types.Of do
156162 """
157163 def struct ( { :% , meta , _ } , struct , args , default_handling , stack , context , of_fun )
158164 when is_atom ( struct ) do
159- # The compiler has already checked the keys are atoms and which ones are required.
160- with { :ok , args_types , context } <-
161- map_reduce_ok ( args , context , fn { key , value } , context when is_atom ( key ) ->
162- with { :ok , type , context } <- of_fun . ( value , stack , context ) do
163- { :ok , { key , type } , context }
164- end
165- end ) do
166- struct ( struct , args_types , default_handling , meta , stack , context )
165+ of_fun = fn arg1 , arg2 , arg3 ->
166+ case of_fun . ( arg1 , arg2 , arg3 ) do
167+ { :ok , type , context } -> { type , context }
168+ { :error , context } -> { dynamic ( ) , context }
169+ { type , context } -> { type , context }
170+ end
167171 end
172+
173+ # The compiler has already checked the keys are atoms and which ones are required.
174+ { args_types , context } =
175+ Enum . map_reduce ( args , context , fn { key , value } , context when is_atom ( key ) ->
176+ { type , context } = of_fun . ( value , stack , context )
177+ { { key , type } , context }
178+ end )
179+
180+ struct ( struct , args_types , default_handling , meta , stack , context )
168181 end
169182
170183 @ doc """
@@ -186,7 +199,7 @@ defmodule Module.Types.Of do
186199 :only_defaults -> [ { :__struct__ , atom ( [ struct ] ) } | defaults ]
187200 end
188201
189- { :ok , dynamic ( closed_map ( pairs ) ) , context }
202+ { dynamic ( closed_map ( pairs ) ) , context }
190203 end
191204
192205 @ doc """
0 commit comments