Match construction of `Array` without adding a type parameter

type
parametric-types

#1

Array(Float64, 3) in 0.6 should be Array{Float64}(3).

If I wanted to make a type that, say, wraps an Array and also stores its length, I can:

mutable struct Wrap{A <: Array{T, 1} where {T}}
  a::A
  l::Int64
end

If I want to use the old syntax (Wrap(Float64, n)) to construct this wrapped array, then I can:

function Wrap(T, n)
  Wrap(Array{T}(n), n)
end

But I don’t see any way to use the following syntax Wrap{Float64}(n) to construct the type above.

If I do want that syntax to be available, (in order to be consistent with Array) I can by including an additional type parameter, and with an inner constructor as follows

mutable struct Wrap{T, A <: Array{T, 1}}
  a::A
  l::Int64
  function Wrap{T}(n) where {T}
    new{T, Array{T, 1}}(Array{T}(n), n)
  end
end

are there any other options? The first approach seems less complicated, except that it doesn’t look like how you construct Array.

(And if I want to dispatch on the eltype of the a field, I would need the repeated T in any case (as of today), right?)


#2

I am not sure I understand why that matters, unless you want Wrap to be syntactically interchangeable with Array; then it is a good choice.

Yes, that seems to be the easiest way to do it.

BTW, I am not sure if length was just for the MWE, but storing may not be necessary as it is a really cheap operation.


#3

You can sort of get what you want by just dropping the <: Array in your type parameter:

julia> struct Wrap{A}
           a::A
           l::Int64
           Wrap{T}(n::Integer) where {T} = new{Vector{T}}(Vector{T}(n), n)
       end

julia> Wrap{Int}(5)
Wrap{Array{Int64,1}}([0, 0, 0, 0, 0], 5)

julia> f(x::W) where {T <: Integer, W <: Wrap{Vector{T}}} = 5
f (generic function with 1 method)

julia> f(Wrap{Int}(5))
5

julia> f(Wrap{Float64}(5))
ERROR: MethodError: no method matching f(::Wrap{Array{Float64,1}})
Closest candidates are:
  f(::W<:Wrap{Array{T<:Integer,1}}) where {T<:Integer, W<:Wrap{Array{T<:Integer,1}}} at REPL[3]:100   

but I’m not sure I’d recommend this. I think your version with the explicit T parameter is more like what SubArray, OffsetArray, etc. do.