How to extract the specific type from an instance of a generic type in julia?
Asked Answered
A

3

6

How do I get the subtype of an instance of an parametric type in julia? For example:

immutable Dog{T <: Number}
    snout::T
end

dog = Dog(5.)
typeof(dog)

...returns Dog{Float64}. Is there a way to get at the type Float64 from the variable dog without referring explicitly to the field snout?

Apogeotropism answered 14/7, 2015 at 20:52 Comment(3)
I'm not sure you mean to use the word "abstract" here. An abstract type is just a node in the type hierarchy and is defined using abstract MyAbstractType. Your type Dog appears to be parametric, immutable, and composite, but not abstract.Shortly
Also, I think the closest you'll get is fieldtype(dog, 1) or fieldtype(dog, :snout). I don't know of a method to return the type parameter of an instance of a parametric type (although it is possible that an undocumented one exists).Shortly
Thank you, I replaced the word "abstract" with "parametric".Apogeotropism
L
9

It depends on your use case. If you are interested in a specific case like this, a good way is to define a function

dogtype{T}(::Dog{T}) = T

Then dogtype(Dog(.5)) will give you Float 64.

This is the kind of pattern that is used to implement the eltype function in base Julia.

Liebig answered 15/7, 2015 at 15:38 Comment(0)
A
2

This works for me:

julia> VERSION
v"0.4.0-dev+5733"

julia> immutable Dog{T <: Number}
           snout::T
       end

julia> dog = Dog(0.5)
Dog{Float64}(0.5)

julia> typeof(dog).parameters[1]
Float64
Anora answered 15/7, 2015 at 20:22 Comment(0)
P
1

No, because the type of dog is Dog{Float64} not Float64. Think of what would be the expected output if you parametrize Dog by more than one type.

The recommended way is to use a method to access a type/immutable fields:

julia> type Foo{T <: Number, S <: AbstractString}
           bar::T
           baz::S
       end

julia> foo = Foo(5.5, "test")
Foo{Float64,ASCIIString}(5.5,"test")

julia> typeof(foo)
Foo{Float64,ASCIIString}

julia> typeof(foo.bar)
Float64

julia> typeof(foo.baz)
ASCIIString

julia> for field in names(Foo)
           @eval $(field)(x::Foo) = x.$field
       end

julia> typeof(bar(foo))
Float64

julia> typeof(baz(foo))
ASCIIString
Prowel answered 14/7, 2015 at 23:45 Comment(2)
Yes, I understand that -- my question in the context of your answer is whether there is a way to extract the types of bar and baz without referring to them by name.Apogeotropism
user3271788, I think Toivo Henningsson's answer is the correct one for you, Tom Breloff's answer does what you want but looks hacky (all for the sake of not referring to an identifier?). What is your use case? Could you expand your question with an example of a language that let you do this and why this is useful?Prowel

© 2022 - 2024 — McMap. All rights reserved.