Yes, arguably typejoin should just walk up the hierarchy and not try
to do fancier joins. However if there are no parameters in common,
e.g.

a = Wow{W, X}()
b = Wow{Y, Z}()

then the result would be Any.

On Wed, Apr 1, 2015 at 11:45 AM, Stefan Karpinski <[email protected]> wrote:
> Arguably typejoin should do that.
>
> On Wed, Apr 1, 2015 at 11:35 AM, Michael Francis <[email protected]>
> wrote:
>>
>> In this instance I'm happy to have the abstract type as the promoted type.
>> E.g. I would like to see this be Array{Foo{Int64},1} and not Array{Foo{K},1}
>> Can I satisfy this with a promote rule ?
>>
>> On Wednesday, April 1, 2015 at 11:29:08 AM UTC-4, Stefan Karpinski wrote:
>>>
>>> This is computed by the promote_type and typejoin functions defined in
>>> promotion.jl:
>>>
>>> https://github.com/JuliaLang/julia/blob/master/base/promotion.jl
>>>
>>>
>>> promote_type tries to find a single concrete type to convert a collection
>>> of types to. As a fallback, if it can't do that, it calls typejoin on the
>>> types, which walks up the type hierarchy and tries to find a common abstract
>>> supertype of its arguments. Since these types don't have any promote_rule
>>> methods, all examples fall back on typejoin, which exhibits the behavior
>>> you're seeing here:
>>>
>>> julia> typejoin(typeof(a))
>>> Wow{Int64,Int64}
>>>
>>> julia> typejoin(typeof(a),typeof(b))
>>> Wow{K,V}
>>>
>>> julia> typejoin(typeof(a),typeof(c))
>>> Foo{Int64}
>>>
>>> julia> typejoin(typeof(a),typeof(b),typeof(c))
>>> Foo{Int64}
>>>
>>> julia> typejoin(typeof(a),typeof(c),typeof(b))
>>> Foo{Int64}
>>>
>>> julia> typejoin(typeof(a),typeof(b),typeof(c),typeof(d))
>>> Foo{K}
>>>
>>>
>>> One way to hook into this system and get different results is to define
>>> promote_rule methods to determine what "wins" when you promote different Wow
>>> and Foo types together. For example, you could define this (requires a
>>> restart dues to #265):
>>>
>>> Base.convert{K,V}(::Type{Wow{K,V}}, x::Wow) = Wow{K,V}()
>>>
>>> Base.promote_rule{K1,V1,K2,V2}(::Type{Wow{K1,V1}}, ::Type{Wow{K2,V2}}) =
>>>     Wow{promote_type(K1,K2),promote_type(V1,V2)}
>>>
>>>
>>> After that [a, b] constructs an Array{Wow{Int64,Float64},1} instead of an
>>> Array{Wow,1}. The conversion method is a bit odd here since Wow doesn't have
>>> any fields, but you would do the appropriate conversions if there were
>>> fields. If there's some appropriate way to pick a common type between Wow
>>> and Foo objects, that can also have promote_rules.
>>>
>>>
>>> On Wed, Apr 1, 2015 at 11:02 AM, Michael Francis <[email protected]>
>>> wrote:
>>>>
>>>> If I run the following, I get the results show to the right (in
>>>> comments), it appears array construction fails to raise to the common
>>>> parent type under certain conditions, is there a way round this?
>>>> Alternatively where is this code implemented ?
>>>>
>>>> abstract Foo{K}
>>>> type Wow{K,V} <: Foo{K} end
>>>> type Bar{K,V} <: Foo{K} end
>>>>
>>>> a = Wow{Int64, Int64}()
>>>> b = Wow{Int64, Float64}()
>>>> c = Bar{Int64, Int64}()
>>>> d = Bar{Int64, String}()
>>>>
>>>> println( "******" )
>>>> println( typeof( [ a ]))          #Array{Wow{Int64,Int64},1}
>>>> println( typeof( [ a, b ]))       #Array{Wow{K,V},1}
>>>> println( typeof( [ a, c ]))       #Array{Foo{Int64},1}
>>>> println( typeof( [ a, b, c ]))    #Array{Foo{Int64},1}
>>>> println( typeof( [ a, c, b ]))    #Array{Foo{Int64},1}
>>>> println( typeof( [ a, b, c, d ])) #Array{Foo{K},1}
>>>
>>>
>

Reply via email to