Thank you, that works. I suppose I will have to use a generated function to
make this type-stable.

On Wed, Aug 17, 2016 at 1:02 AM, Mauro <mauro...@runbox.com> wrote:

>
> 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}
>

Reply via email to