You (kinda) have to provide an outer constructor as well.
julia> immutable ArrayWrapper{T,N,AT <: AbstractArray} <: AbstractArray{T,N}
arr::AT
function ArrayWrapper(arr)
@assert T==eltype(arr) && length(size(arr))==N
new(arr)
end
end
Without outer constructor you need to specify the parameters:
julia> ArrayWrapper{Float64, 2, Array{Float64,2}}(rand(3,3));
If you do it wrong the assertion will error:
julia> ArrayWrapper{Float64, 3, Array{Float64,2}}(rand(3,3));
ERROR: AssertionError: T == eltype(arr) && length(size(arr)) == N
in call at none:4
Probably define this outer constructor:
julia> ArrayWrapper{AT<:AbstractArray}(arr::AT) = ArrayWrapper{eltype(arr),
length(size(arr)), AT}(arr)
ArrayWrapper{T,N,AT<:AbstractArray{T,N}}
julia> ArrayWrapper(rand(4,4));
Note that I suppressed output because there is some error in the show
method. I think you have to provide certain functions to make it work.
See http://docs.julialang.org/en/release-0.4/manual/interfaces/
On Mon, 2015-11-30 at 10:18, Andrei Zh <[email protected]> wrote:
> Hmm, seems like this gives an error when constructing a type:
>
> julia> ArrayWrapper(rand(3, 4))
> ERROR: MethodError: `convert` has no method matching convert(::Type{
> ArrayWrapper{T,N,AT<:AbstractArray{T,N}}}, ::Array{Float64,2})
> This may have arisen from a call to the constructor ArrayWrapper{T,N,AT<:
> AbstractArray{T,N}}(...),
> since type constructors fall back to convert methods.
> Closest candidates are:
> call{T}(::Type{T}, ::Any)
> convert{T}(::Type{T}, ::T)
> in call at essentials.jl:57
>
> Moving constructor outside type definition doesn't work too.
>
> On Monday, November 30, 2015 at 12:00:10 PM UTC+3, Mauro wrote:
>>
>> > I'm trying to do something like this (which doesn't compile in its
>> current
>> > form):
>> >
>> > type ArrayWrapper{T,N,AT <: AbstractArray{T,N}} <: AbstractArray{T,N}
>> > arr::AT{T,N}
>> > end
>> >
>> > That is:
>> >
>> > - wrapper around any type AT inherited from AbstractArray{T,N}
>> > - wrapper should be itself parametrized by T and N
>> > - wrapper should itself extend AbstractArray{T,N}
>> >
>> > The code above currently gives an error:
>> >
>> > ERROR: TypeError: instantiate_type: expected TypeConstructor, got
>> TypeVar
>> >
>> >
>> > and the closest thing that works looks like this:
>> >
>> > type ArrayWrapper{T,N,AT <: AbstractArray} <: AbstractArray{T,N}
>> > arr::AT
>> > end
>> >
>> > which looks too unconstrained.
>> >
>> > Is there a way to get what I need?
>>
>> If you're ok with using immutable (note, you can still modify the array,
>> just not its binding), this should work:
>>
>> immutable ArrayWrapper{T,N,AT <: AbstractArray} <: AbstractArray{T,N}
>> arr::AT
>> function ArrayWrapper(arr)
>> @assert T==eltype(arr) && length(size(arr))==N
>> new(arr)
>> end
>> end
>>