On Wed, 2016-08-17 at 05:04, Cedric St-Jean <cedric.stj...@gmail.com> wrote: > Hi, I'm writing a function to recursively traverse a heterogeneous tree of > immutables and replace certain elements of it. So far I have: > > subst(x::Number, assoc::Associative) = x > subst(x::Variable, assoc::Associative) = get(assoc, x, x) > subst{T}(x::T, assoc::Associative) = T([subst(getfield(x, f), assoc) for f > in fieldnames(x)]...) > > I.e. numbers are kept as is, variables are possible replaced, and composite > structures are recursively traversed. This doesn't look very > compiler-friendly, so question 1 is if there's a better way of writing > this, short of manually writing one `subst` for each type. > > My problem is that the above fails when the composite structure is > parametric, since a Variable might be replaced by a number. Eg. `Pair(2, > Variable(:x))` will become `Pair(2, 5)`, and that's a different type, so > the T([ ]...) line fails because T is Pair{Int, Variable}. > > Question 2 is: given T = Pair{Int, Int}, is there any way to recover Pair? > Pair{Int, Int}.name returns Pair, but as a TypeName.
julia> Pair{Int, Int}.name.primary Pair{A,B} But it's not type stable: julia> f(z) = z.name.primary f (generic function with 1 method) julia> @code_warntype f(Pair{Int,Int}) Variables: #self#::#f z::Type{Pair{Int64,Int64}} Body: begin return (Core.getfield)((Core.getfield)(z::Type{Pair{Int64,Int64}},:name)::TypeName,:primary)::Type{T} end::Type{T}