递归无单元素类型

时间:2017-12-06 17:46:37

标签: arrays recursion types julia

我正在尝试提供一个函数,它给出了递归无单元素类型。例如,为了缩短它,我们可以将其称为ruet,我希望:

A = zeros(5,5)
reut(A) == Float64
using Unitful
A = zeros(5,5)*1u"kg"
reut(A) == Float64
AA = [zeros(5,5) for i in 1:5]
reut(AA) == Array{Float64,2}
AofA = [copy(A) for i in 1:5]
reut(AofA) == Array{Float64,2}
using StaticArrays
AofSA = [@SVector [2.0,3.0] for i in 1:5]
reut(AofSA) == SVector{2,Float64}
AofuSA = [@SVector [2.0u"kg",3.0u"kg"] for i in 1:5]
reut(AofuSA) == SVector{2,Float64}

所以基本上剥离了单位,但仍然返回正确的元素类型,这可能是一个数组。它的阵列部分很难。我可以推算:

recursive_eltype(a) = recursive_eltype(eltype(a))
recursive_eltype{T<:Number}(a::Type{T}) = eltype(a)

然后得到无单位元素类型:

uEltype = recursive_eltype(u)
uEltypeNoUnits = typeof(one(uEltype))

但是这总是数字类型,当它是一个数组数组时,我似乎无法找到一个很好的方法来取回数组类型,即这个方法返回{{1在上面的所有例子中。我想知道是否需要在静态数组上调度并使用Float64

请注意,如果可能,我希望解决方案对Unitful.jl没有要求。获取数字的无单位类型可以通过similar_type完成,所以我认为这应该是可能的。

(与Julia问题有些相关:https://github.com/JuliaLang/julia/issues/22216

2 个答案:

答案 0 :(得分:2)

我想出了:

{{1}}

这仍然不完全通用,但适用于各种各样的事情。

答案 1 :(得分:1)

使用Julia版本0.6.2-something(代码肯定不是非常便携):

function _reut(T)
    try
        T.name == Quantity.body.body.body.name && return _reut(T.parameters[1])
        getfield(T.name.module, T.name.name){_reut.(collect(T.parameters))...}
    catch
        T
    end
end
reut(T) = _reut(eltype(T))

问题中的测试通过了。仍然无法推断,但将eval替换为getfield(Module,Symbol)。你在哪里得到这些问题?