http://docs.julialang.org/en/stable/manual/faq/#how-should-i-declare-abstract-container-type-fields

On Monday, November 30, 2015 10:44:58 AM Mauro wrote:
> 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