Get type of field in parametric type

parametric-types

#1

Let’s say I have a parametric type defined as

mutable struct Example{T,N<:Real}
  a::T
  b::Array{N,1}
end

I can create an object with something like,

x = Example(:a, [1, 2, 3])

Then the type of x is Example{Symbol, Int64} – is there a way to get Int64? So far I found

eltype(fieldtype(typeof(x), 2))

which works, but I was wondering whether there is a more julianesque way of getting the same result?


#2
Base.@pure get_type_parameter(x) = typeof(x).parameters[2]

That infers.

julia> Base.@pure get_type_parameter(x) = typeof(x).parameters[2]
get_type_parameter (generic function with 2 methods)

julia> @code_warntype get_type_parameter(rand(3))
Variables:
  #self# <optimized out>
  x <optimized out>

Body:
  begin
      return $(Expr(:invoke, MethodInstance for getindex(::SimpleVector, ::Int64), :(Main.getindex), :((Core.getfield)(Array{Float64,1}, :parameters)::SimpleVector), 2))
  end::Int64

The more general form

Base.@pure get_type_parameter(x,i) = typeof(x).parameters[i]

needs IPO from v0.7 to infer.


#3

You probably thought about this already, but the Julian way would be to dispatch on Example every time you need to use the type parameter T. For example:

julia> findparam(ex::Example{T, N}) where {T, N} = N
findparam (generic function with 1 method)

julia> x = Example(:a, [1, 2, 3])
Example{Symbol,Int64}(:a, [1, 2, 3])

julia> findparam(x)
Int64

#4

This is precisely what I was failing to express! Thanks!


#5

Please don’t suggest the use of this annotation. It’s nearly always wrong, and thus actively unhelpful to mention it, then have to explain that it also causes inference to be fatally wrong. It doesn’t infer, it does the opposite: it tells inference that it’s OK to totally disregard correctness. (piever’s solution is correct).