This problem is quite common in the LinAlg code. We have two type of definitions to handle the conversion of the element types. First an idea due to Jeff as implemented in
https://github.com/JuliaLang/julia/blob/237cdab7100b29a6769313391b1f8d2563ada06e/base/linalg/triangular.jl#L20 and https://github.com/JuliaLang/julia/blob/237cdab7100b29a6769313391b1f8d2563ada06e/base/linalg/symmetric.jl#L34 These create maybe-aliased objects which can be problem in the destructive linalg functions so therefore Simon Kornblith invented copy_oftype which you can see example of here https://github.com/JuliaLang/julia/blob/237cdab7100b29a6769313391b1f8d2563ada06e/base/linalg/symmetric.jl#L34 Notice that it requires two method definitions for each type. 2015-04-22 8:57 GMT-04:00 Tim Holy <[email protected]>: > As Jeff says...this is why `similar` exists. > > --Tim > > On Wednesday, April 22, 2015 10:03:02 AM Mauro wrote: > > Thanks Jameson and here the context: > > > > # Initializes an array which has a's container but b's eltype > > function f(a::AbstractVector, b::AbstractVector) > > Eb = eltype(b) # this is type-stable > > Ca = typeof(a).name.primary # this is not type-stable > > return Ca(Eb, 5) # assumes Ca supports the normal Array > > constructor end > > > > The last line would probably better use copy+convert but for that I > > still need to make Ca{Eb,1}. Note that Ca is always a leaftype and I > > don't want to climb the type hierarchy, so I think your remark about the > > subtypes does not apply. > > > > Here the typed code: > > julia> @code_warntype f([1,2], [1.]) > > Variables: > > a::Array{Int64,1} > > b::Array{Float64,1} > > Eb::Type{Float64} > > Ca::Type{T} # <--- > > > > Body: > > begin # none, line 3: > > Eb = Float64 # line 4: > > Ca = > > > (top(getfield))((top(getfield))(typeof(a::Array{Int64,1})::Type{Array{Int64 > > ,1}},:name)::TypeName,:primary)::Type{T} # line 5: return > > (Ca::Type{T})(Eb::Type{Float64},5)::Any > > end::Any > > > > Thanks! > > > > On Tue, 2015-04-21 at 22:56, Jameson Nash <[email protected]> wrote: > > > Your question presupposes that you can write useful generic code with > the > > > return result, but does not provide any context on your problem. When a > > > similar question was asked previously on the mailing list, I recall > > > pointing out that the code the author was attempting to write was not > > > going > > > to function as intended. Perhaps you can provide some more context? > > > > > > The observation that I am making is that you cannot arbitrarily pick > apart > > > a type and expect everything to line up afterwards. For example, it is > > > possible to have the following: > > > abstract AbstractTy{A,B} > > > type Ty1 <: AbstractTy{Int, Float64} end > > > type Ty2{B,A} <: AbstractTy{A,B} end > > > > > > So you can't generically reconstruct some arbitrary subtype by some > > > generic > > > rearrangement of its type parameters. > > > > > > On Tue, Apr 21, 2015 at 4:34 PM Mauro <[email protected]> wrote: > > >> I have a parameterized type and want to get the primary-type. For > > >> example, I got > > >> > > >> a = Array{Int,2} > > >> > > >> is there a type-stable way to get Array? This is non-type stable: > > >> > > >> f(t::Type) = t.name.primary > > >> > > >> as the inferred return type is Type. > > >> > > >> This does not work: > > >> > > >> f{T, S}(::Type{T{S...}}) = T > > >> > > >> Any ideas? Thanks, M > >
