11# promote_type/promote_typejoin already works for Identity and Nothing (aka Options)
22# ==========================================================================
33
4- # nothing todo, as `Nothing` is already super well supported for promote_type and promote_typejoin
4+ # promote_type
5+ # ------------
6+ # seamingly nothing todo, everything works out of the box
7+ # probably as `Nothing` is already super well supported for promote_type and promote_typejoin
8+
9+
10+ # promote_typejoin
11+ # ----------------
12+ # This does not seem to work out of the box however, a bit surprisingly.
13+ # One reason seems to be that Identity is not a concrete type.
14+
15+ # only the abstract one is missing in Base
16+ Base. promote_typejoin (:: Type{Nothing} , :: Type{Identity} ) = Option
17+ Base. promote_typejoin (:: Type{Identity} , :: Type{Nothing} ) = Option
18+
19+ Base. promote_typejoin (:: Type{Option{T1}} , :: Type{Identity{T2}} ) where {T1, T2} = Option
20+ Base. promote_typejoin (:: Type{Identity{T2}} , :: Type{Option{T1}} ) where {T1, T2} = Option
21+
22+ Base. promote_typejoin (:: Type{Option{T}} , :: Type{Nothing} ) where {T} = Option{T}
23+ Base. promote_typejoin (:: Type{Nothing} , :: Type{Option{T}} ) where {T} = Option{T}
24+
25+ Base. promote_typejoin (:: Type{Option} , :: Type{Nothing} ) = Option
26+ Base. promote_typejoin (:: Type{Nothing} , :: Type{Option} ) = Option
27+
28+
29+
30+
531
632
733# promote_type/promote_typejoin should work with Identity and Const (aka Either)
834# ==========================================================================
935
36+ # promote_type ---------------------------------------------------------------------------------
1037# promote_type only has to deal with concrete types, including Unions in our case
1138
1239# promote_type Const & Identity
@@ -22,11 +49,13 @@ Base.promote_rule(::Type{Const}, ::Type{Either{L, R}}) where {L, R} = Either{<:A
2249Base. promote_rule (:: Type{Const{L}} , :: Type{Either{L, R}} ) where {L, R} = Either{L, R}
2350Base. promote_rule (:: Type{Const{L1}} , :: Type{Either{L2, R}} ) where {L1, R, L2 <: L1 } = Either{L1, R}
2451Base. promote_rule (:: Type{Const{L2}} , :: Type{Either{L1, R}} ) where {L1, R, L2 <: L1 } = Either{L1, R}
52+ Base. promote_rule (:: Type{Const{L2}} , :: Type{Either{L1, R}} ) where {L1, R, L2} = Either{<: Any , R}
2553
2654Base. promote_rule (:: Type{Const} , :: Type{Either{L, <:Any}} ) where {L} = Either
2755Base. promote_rule (:: Type{Const{L}} , :: Type{Either{L, <:Any}} ) where {L} = Either{L, <: Any }
2856Base. promote_rule (:: Type{Const{L1}} , :: Type{Either{L2, <:Any}} ) where {L1, L2 <: L1 } = Either{L1, <: Any }
2957Base. promote_rule (:: Type{Const{L2}} , :: Type{Either{L1, <:Any}} ) where {L1, L2 <: L1 } = Either{L1, <: Any }
58+ Base. promote_rule (:: Type{Const{L1}} , :: Type{Either{L2, <:Any}} ) where {L1, L2} = Either
3059
3160Base. promote_rule (:: Type{Const} , :: Type{Either} ) = Either
3261
@@ -38,11 +67,13 @@ Base.promote_rule(::Type{Identity}, ::Type{Either{L, R}}) where {L, R} = Either{
3867Base. promote_rule (:: Type{Identity{R}} , :: Type{Either{L, R}} ) where {L, R} = Either{L, R}
3968Base. promote_rule (:: Type{Identity{R1}} , :: Type{Either{L, R2}} ) where {L, R1, R2 <: R1 } = Either{L, R1}
4069Base. promote_rule (:: Type{Identity{R2}} , :: Type{Either{L, R1}} ) where {L, R1, R2 <: R1 } = Either{L, R1}
70+ Base. promote_rule (:: Type{Identity{R2}} , :: Type{Either{L, R1}} ) where {L, R1, R2} = Either{L, <: Any }
4171
4272Base. promote_rule (:: Type{Identity} , :: Type{Either{<:Any, R}} ) where {R} = Either
4373Base. promote_rule (:: Type{Identity{R}} , :: Type{Either{<:Any, R}} ) where {R} = Either{<: Any , R}
4474Base. promote_rule (:: Type{Identity{R1}} , :: Type{Either{<:Any, R2}} ) where {R1, R2 <: R1 } = Either{<: Any , R1}
4575Base. promote_rule (:: Type{Identity{R2}} , :: Type{Either{<:Any, R1}} ) where {R1, R2 <: R1 } = Either{<: Any , R1}
76+ Base. promote_rule (:: Type{Identity{R2}} , :: Type{Either{<:Any, R1}} ) where {R1, R2} = Either
4677
4778Base. promote_rule (:: Type{Identity} , :: Type{Either} ) = Either
4879
@@ -57,31 +88,215 @@ Base.promote_rule(::Type{Either{L, R1}}, ::Type{Either{L, R2}}) where {L, R1, R2
5788Base. promote_rule (:: Type{Either{L1, R1}} , :: Type{Either{L2, R2}} ) where {L1, R1, L2 <: L1 , R2 <: R1 } = Either{L1, R1}
5889Base. promote_rule (:: Type{Either{L2, R1}} , :: Type{Either{L1, R2}} ) where {L1, R1, L2 <: L1 , R2 <: R1 } = Either{L1, R1}
5990
91+ Base. promote_rule (:: Type{Either{L1, R}} , :: Type{Either{L2, R}} ) where {L1, R, L2} = Either{<: Any , R}
92+ Base. promote_rule (:: Type{Either{L, R1}} , :: Type{Either{L, R2}} ) where {L, R1, R2} = Either{L, <: Any }
93+ Base. promote_rule (:: Type{Either{L1, R1}} , :: Type{Either{L2, R2}} ) where {L1, R1, L2, R2} = Either
94+
6095Base. promote_rule (:: Type{Either{L, <:Any}} , :: Type{Either{L, <:Any}} ) where {L} = Either{L, <: Any }
6196Base. promote_rule (:: Type{Either{L1, <:Any}} , :: Type{Either{L2, <:Any}} ) where {L1, L2 <: L1 } = Either{L1, <: Any }
97+ Base. promote_rule (:: Type{Either{L1, <:Any}} , :: Type{Either{L2, <:Any}} ) where {L1, L2} = Either
6298
63- Base. promote_rule (:: Type{Either{<:Any, R}} , :: Type{Either{<:Any, R}} ) where {L, R} = Either{<: Any , R}
64- Base. promote_rule (:: Type{Either{<:Any, R1}} , :: Type{Either{<:Any, R2}} ) where {L, R1, R2 <: R1 } = Either{<: Any , R1}
99+ Base. promote_rule (:: Type{Either{<:Any, R}} , :: Type{Either{<:Any, R}} ) where {R} = Either{<: Any , R}
100+ Base. promote_rule (:: Type{Either{<:Any, R1}} , :: Type{Either{<:Any, R2}} ) where {R1, R2 <: R1 } = Either{<: Any , R1}
101+ Base. promote_rule (:: Type{Either{<:Any, R1}} , :: Type{Either{<:Any, R2}} ) where {R1, R2} = Either
65102
66103# NOTE we cannot use `Base.promote_rule(::Type{<:Either}, ::Type{<:Either}) = Either` as apparently this interferes
67104# with more concrete implementations of promote_rule
68105# promote_type seem to assume, that you really only define promote_rule for concrete types
69106Base. promote_rule (:: Type{Either} , :: Type{Either} ) = Either
70107
71108
72- # promote_typejoin
109+ # promote_typejoin ---------------------------------------------------------------
110+ # promote_typejoin never converts types, but always returns the next abstract type in the hierarchy, including Unions
111+ # further, promote_typejoin(A, B) and promote_typejoin(B, A) need both to be defined (unlike promote_rule)
112+
113+ # promote_typejoin Const & Identity
114+ # -----------------------------
115+
116+ Base. promote_typejoin (:: Type{C} , :: Type{I} ) where {C<: Const , I<: Identity } = Union{C, I}
117+ Base. promote_typejoin (:: Type{I} , :: Type{C} ) where {C<: Const , I<: Identity } = Union{C, I}
118+
119+
120+ # promote_typejoin Const & Either
73121# -----------------------------
74122
75- # We also support `promote_typejoin`, as the semantics between promote_typejoin and promote_type overlap
76- # in our case of Unions (similar to how they are already defined for Nothing and Missing in Base).
77- # In addition note that `promote_typejoin` has to be defined for both flipped and non-flipped versions.
78- # We solve this by referring to the symmetric `promote_type` instead of the asymmtric `promote_rule`.
79- Base. promote_typejoin (:: Type{E1} , :: Type{E2} ) where {E1<: OptionEither , E2<: OptionEither } = promote_type (E1, E2)
80- # TODO typejoin should actually not combine Identity{AbstractString} and Identity{String} to Identity{AbstractString}
81- # hence we really need to redefine everything alike to be safe.
123+ Base. promote_typejoin (:: Type{Const} , :: Type{Either{L, R}} ) where {L, R} = Either{<: Any , R}
124+ Base. promote_typejoin (:: Type{Either{L, R}} , :: Type{Const} ) where {L, R} = Either{<: Any , R}
125+
126+ Base. promote_typejoin (:: Type{Const{L}} , :: Type{Either{L, R}} ) where {L, R} = Either{L, R}
127+ Base. promote_typejoin (:: Type{Either{L, R}} , :: Type{Const{L}} ) where {L, R} = Either{L, R}
128+
129+ Base. promote_typejoin (:: Type{Const{L2}} , :: Type{Either{L1, R}} ) where {L1, R, L2} = Either{<: Any , R}
130+ Base. promote_typejoin (:: Type{Either{L1, R}} , :: Type{Const{L2}} ) where {L1, R, L2} = Either{<: Any , R}
131+
132+
133+ Base. promote_typejoin (:: Type{Const} , :: Type{Either{L, <:Any}} ) where {L} = Either
134+ Base. promote_typejoin (:: Type{Either{L, <:Any}} , :: Type{Const} ) where {L} = Either
135+
136+ Base. promote_typejoin (:: Type{Const{L}} , :: Type{Either{L, <:Any}} ) where {L} = Either{L, <: Any }
137+ Base. promote_typejoin (:: Type{Either{L, <:Any}} , :: Type{Const{L}} ) where {L} = Either{L, <: Any }
138+
139+ Base. promote_typejoin (:: Type{Const{L1}} , :: Type{Either{L2, <:Any}} ) where {L1, L2} = Either
140+ Base. promote_typejoin (:: Type{Either{L2, <:Any}} , :: Type{Const{L1}} ) where {L1, L2} = Either
141+
142+
143+ Base. promote_typejoin (:: Type{Const} , :: Type{Either} ) = Either
144+ Base. promote_typejoin (:: Type{Either} , :: Type{Const} ) = Either
145+
146+
147+ # promote_typejoin Identity & Either
148+ # -----------------------------
149+
150+ Base. promote_typejoin (:: Type{Identity} , :: Type{Either{L, R}} ) where {L, R} = Either{L, <: Any }
151+ Base. promote_typejoin (:: Type{Either{L, R}} , :: Type{Identity} ) where {L, R} = Either{L, <: Any }
152+
153+ Base. promote_typejoin (:: Type{Identity{R}} , :: Type{Either{L, R}} ) where {L, R} = Either{L, R}
154+ Base. promote_typejoin (:: Type{Either{L, R}} , :: Type{Identity{R}} ) where {L, R} = Either{L, R}
155+
156+ Base. promote_typejoin (:: Type{Identity{R2}} , :: Type{Either{L, R1}} ) where {L, R1, R2} = Either{L, <: Any }
157+ Base. promote_typejoin (:: Type{Either{L, R1}} , :: Type{Identity{R2}} ) where {L, R1, R2} = Either{L, <: Any }
158+
159+
160+ Base. promote_typejoin (:: Type{Identity} , :: Type{Either{<:Any, R}} ) where {R} = Either
161+ Base. promote_typejoin (:: Type{Either{<:Any, R}} , :: Type{Identity} ) where {R} = Either
162+
163+ Base. promote_typejoin (:: Type{Identity{R}} , :: Type{Either{<:Any, R}} ) where {R} = Either{<: Any , R}
164+ Base. promote_typejoin (:: Type{Either{<:Any, R}} , :: Type{Identity{R}} ) where {R} = Either{<: Any , R}
165+
166+ Base. promote_typejoin (:: Type{Identity{R2}} , :: Type{Either{<:Any, R1}} ) where {R1, R2} = Either
167+ Base. promote_typejoin (:: Type{Either{<:Any, R1}} , :: Type{Identity{R2}} ) where {R1, R2} = Either
168+
169+
170+ Base. promote_typejoin (:: Type{Identity} , :: Type{Either} ) = Either
171+ Base. promote_typejoin (:: Type{Either} , :: Type{Identity} ) = Either
172+
173+
174+ # promote_type Either & Either
175+ # -----------------------------
176+
177+ # we need to be cautious here, as we cannot dispatch on Type{<:Either{<:Any, R}} or similar, because R might not be defined
178+ Base. promote_typejoin (:: Type{Either{L, R}} , :: Type{Either{L, R}} ) where {L, R} = Either{L, R}
179+
180+ Base. promote_typejoin (:: Type{Either{L1, R}} , :: Type{Either{L2, R}} ) where {L1, R, L2} = Either{<: Any , R}
181+
182+ Base. promote_typejoin (:: Type{Either{L, R1}} , :: Type{Either{L, R2}} ) where {L, R1, R2} = Either{L, <: Any }
183+
184+ Base. promote_typejoin (:: Type{Either{L1, R1}} , :: Type{Either{L2, R2}} ) where {L1, R1, L2, R2} = Either
185+
186+
187+ Base. promote_typejoin (:: Type{Either{L, <:Any}} , :: Type{Either{L, <:Any}} ) where {L} = Either{L, <: Any }
188+
189+ Base. promote_typejoin (:: Type{Either{L1, <:Any}} , :: Type{Either{L2, <:Any}} ) where {L1, L2} = Either
190+
191+
192+ Base. promote_typejoin (:: Type{Either{<:Any, R}} , :: Type{Either{<:Any, R}} ) where {L, R} = Either{<: Any , R}
193+
194+ Base. promote_typejoin (:: Type{Either{<:Any, R1}} , :: Type{Either{<:Any, R2}} ) where {R1, R2} = Either
195+
196+
197+ Base. promote_typejoin (:: Type{Either} , :: Type{Either} ) = Either
198+
199+
200+
82201
83202
84203# promote_type/promote_typejoin should work with all three Identity, Nothing and Const (aka OptionEither)
85204# ==========================================================================
86205
206+ # promote_type
207+ # ------------
87208# nothing todo, as `Nothing` is already super well supported for promote_type and promote_typejoin
209+
210+
211+ # promote_typejoin
212+ # ----------------
213+
214+ # we have to do something here
215+
216+ # Nothing
217+ # - - - -
218+
219+ Base. promote_typejoin (:: Type{Nothing} , :: Type{OptionEither{L, R}} ) where {L, R} = OptionEither{L, R}
220+ Base. promote_typejoin (:: Type{OptionEither{L, R}} , :: Type{Nothing} ) where {L, R} = OptionEither{L, R}
221+
222+ Base. promote_typejoin (:: Type{Nothing} , :: Type{OptionEither{L, <:Any}} ) where {L} = OptionEither{L, <: Any }
223+ Base. promote_typejoin (:: Type{OptionEither{L, <:Any}} , :: Type{Nothing} ) where {L} = OptionEither{L, <: Any }
224+
225+ Base. promote_typejoin (:: Type{Nothing} , :: Type{OptionEither{<:Any, R}} ) where {R} = OptionEither{<: Any , R}
226+ Base. promote_typejoin (:: Type{OptionEither{<:Any, R}} , :: Type{Nothing} ) where {R} = OptionEither{<: Any , R}
227+
228+ Base. promote_typejoin (:: Type{Nothing} , :: Type{OptionEither} ) = OptionEither
229+ Base. promote_typejoin (:: Type{OptionEither} , :: Type{Nothing} ) = OptionEither
230+
231+
232+ # Const
233+ # - - -
234+
235+ Base. promote_typejoin (:: Type{Const{L}} , :: Type{OptionEither{L, R}} ) where {L, R} = OptionEither{L, R}
236+ Base. promote_typejoin (:: Type{OptionEither{L, R}} , :: Type{Const{L}} ) where {L, R} = OptionEither{L, R}
237+
238+ Base. promote_typejoin (:: Type{Const{L1}} , :: Type{OptionEither{L2, R}} ) where {L1, L2, R} = OptionEither{<: Any , R}
239+ Base. promote_typejoin (:: Type{OptionEither{L2, R}} , :: Type{Const{L1}} ) where {L1, L2, R} = OptionEither{<: Any , R}
240+
241+ Base. promote_typejoin (:: Type{Const{L}} , :: Type{OptionEither{<:Any, R}} ) where {L, R} = OptionEither{<: Any , R}
242+ Base. promote_typejoin (:: Type{OptionEither{<:Any, R}} , :: Type{Const{L}} ) where {L, R} = OptionEither{<: Any , R}
243+
244+ Base. promote_typejoin (:: Type{Const{L}} , :: Type{OptionEither{L, <:Any}} ) where {L} = OptionEither{L, <: Any }
245+ Base. promote_typejoin (:: Type{OptionEither{L, <:Any}} , :: Type{Const{L}} ) where {L, R} = OptionEither{L, <: Any }
246+
247+ Base. promote_typejoin (:: Type{Const{L1}} , :: Type{OptionEither{L2, <:Any}} ) where {L1, L2} = OptionEither
248+ Base. promote_typejoin (:: Type{OptionEither{L2, <:Any}} , :: Type{Const{L1}} ) where {L1, L2} = OptionEither
249+
250+ Base. promote_typejoin (:: Type{Const{L}} , :: Type{OptionEither} ) where {L} = OptionEither
251+ Base. promote_typejoin (:: Type{OptionEither} , :: Type{Const{L}} ) where {L} = OptionEither
252+
253+
254+
255+ Base. promote_typejoin (:: Type{Const} , :: Type{OptionEither{L, R}} ) where {L, R} = OptionEither{<: Any , R}
256+ Base. promote_typejoin (:: Type{OptionEither{L, R}} , :: Type{Const} ) where {L, R} = OptionEither{<: Any , R}
257+
258+ Base. promote_typejoin (:: Type{Const} , :: Type{OptionEither{L, <:Any}} ) where {L} = OptionEither
259+ Base. promote_typejoin (:: Type{OptionEither{L, <:Any}} , :: Type{Const} ) where {L} = OptionEither
260+
261+ Base. promote_typejoin (:: Type{Const} , :: Type{OptionEither{<:Any, R}} ) where {R} = OptionEither{<: Any , R}
262+ Base. promote_typejoin (:: Type{OptionEither{<:Any, R}} , :: Type{Const} ) where {R} = OptionEither{<: Any , R}
263+
264+ Base. promote_typejoin (:: Type{Const} , :: Type{OptionEither} ) = OptionEither
265+ Base. promote_typejoin (:: Type{OptionEither} , :: Type{Const} ) = OptionEither
266+
267+
268+ # Identity
269+ # - - - - -
270+
271+
272+ Base. promote_typejoin (:: Type{Identity{R}} , :: Type{OptionEither{L, R}} ) where {L, R} = OptionEither{L, R}
273+ Base. promote_typejoin (:: Type{OptionEither{L, R}} , :: Type{Identity{R}} ) where {L, R} = OptionEither{L, R}
274+
275+ Base. promote_typejoin (:: Type{Identity{R1}} , :: Type{OptionEither{L, R2}} ) where {L, R1, R2} = OptionEither{L, <: Any }
276+ Base. promote_typejoin (:: Type{OptionEither{L, R2}} , :: Type{Identity{R1}} ) where {L, R1, R2} = OptionEither{L, <: Any }
277+
278+ Base. promote_typejoin (:: Type{Identity{R}} , :: Type{OptionEither{L, <:Any}} ) where {L, R} = OptionEither{L, <: Any }
279+ Base. promote_typejoin (:: Type{OptionEither{L, <:Any}} , :: Type{Identity{R}} ) where {L, R} = OptionEither{L, <: Any }
280+
281+ Base. promote_typejoin (:: Type{Identity{R}} , :: Type{OptionEither{<:Any, R}} ) where {R} = OptionEither{<: Any , R}
282+ Base. promote_typejoin (:: Type{OptionEither{<:Any, R}} , :: Type{Identity{R}} ) where {L, R} = OptionEither{<: Any , R}
283+
284+ Base. promote_typejoin (:: Type{Identity{R1}} , :: Type{OptionEither{<:Any, R2}} ) where {R1, R2} = OptionEither
285+ Base. promote_typejoin (:: Type{OptionEither{<:Any, R2}} , :: Type{Identity{R1}} ) where {R1, R2} = OptionEither
286+
287+ Base. promote_typejoin (:: Type{Identity{R}} , :: Type{OptionEither} ) where {R} = OptionEither
288+ Base. promote_typejoin (:: Type{OptionEither} , :: Type{Identity{R}} ) where {R} = OptionEither
289+
290+
291+
292+ Base. promote_typejoin (:: Type{Identity} , :: Type{OptionEither{L, R}} ) where {L, R} = OptionEither{L, <: Any }
293+ Base. promote_typejoin (:: Type{OptionEither{L, R}} , :: Type{Identity} ) where {L, R} = OptionEither{L, <: Any }
294+
295+ Base. promote_typejoin (:: Type{Identity} , :: Type{OptionEither{<:Any, R}} ) where {R} = OptionEither
296+ Base. promote_typejoin (:: Type{OptionEither{<:Any, R}} , :: Type{Identity} ) where {R} = OptionEither
297+
298+ Base. promote_typejoin (:: Type{Identity} , :: Type{OptionEither{L, <:Any}} ) where {L} = OptionEither{L, <: Any }
299+ Base. promote_typejoin (:: Type{OptionEither{L, <:Any}} , :: Type{Identity} ) where {L} = OptionEither{L, <: Any }
300+
301+ Base. promote_typejoin (:: Type{Identity} , :: Type{OptionEither} ) = OptionEither
302+ Base. promote_typejoin (:: Type{OptionEither} , :: Type{Identity} ) = OptionEither
0 commit comments