Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the parameter-less type

Tags:

types

julia

I need to get the parameter-less version of a type. For example, lets say I have x = [0.1,0.2,0.3]. Then typeof(x)==Array{Float64,1}. How do I make a function (or does one exist?) parameterless_type(x) == Array? I need to get this in a generic form in order to access the constructor without the type parameters in it.

like image 631
Chris Rackauckas Avatar asked Feb 14 '17 15:02

Chris Rackauckas


2 Answers

The proper way, compatible with both 0.5 and 0.6, is to use Compat.

julia> using Compat

julia> Compat.TypeUtils.typename(Array{Int, 2})
Array

julia> Compat.TypeUtils.typename(Union{Int, Float64})
ERROR: typename does not apply to unions whose components have different typenames
Stacktrace:
 [1] typename(::Union) at ./essentials.jl:119

julia> Compat.TypeUtils.typename(Union{Vector, Matrix})
Array
like image 62
Fengyang Wang Avatar answered Nov 19 '22 22:11

Fengyang Wang


This seems to work on 0.5

julia> typeof(a)
Array{Float64,1}

julia> (typeof(a).name.primary)([1 2 3])
1×3 Array{Int64,2}:
1  2  3

Edit 1:

Thanks to tholy's comment and the ColorTypes.jl package, a solution for 0.6 is:

julia> (typeof(a).name.wrapper)([1 2 3])
1×3 Array{Int64,2}:
 1  2  3

Edit 2:

Fengyang Wang convinced me, that using typename is necessary. In particular, Array{Int}.name fails on 0.6 because Array{Int} is now of type UnionAll. A definition working on 0.5 and 0.6 is

using Compat.TypeUtils: typename

if :wrapper in fieldnames(TypeName)
    parameterless_type(T::Type) = typename(T).wrapper
else
    parameterless_type(T::Type) = typename(T).primary
end

parameterless_type(x) = parameterless_type(typeof(x))

With that, it is

parameterless_type([0.1,0.2,0.3]) == Array
parameterless_type(Array{Int}) == Array
like image 27
tim Avatar answered Nov 19 '22 20:11

tim