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