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
>>

Reply via email to