Thanks, Mauro and Tim, now it's much clearer.

On Mon, Nov 30, 2015 at 2:13 PM, Tim Holy <[email protected]> wrote:

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