Try:

# this one for any AbstractFoo that is NOT Foo1
> julia> Base.getindex(foo::AbstractFoo, I...) = Foo2(foo.data[I...])
> getindex (generic function with 185 methods)
>


> julia> Base.getindex(foo::Foo1, I...) = Foo1(foo.data[I...])
> getindex (generic function with 184 methods)
>


> julia> f1 = Foo1{2,Float64}(rand(2,2))
> Error showing value of type Foo1{2,Float64}:
> ERROR: MethodError: `size` has no method matching
> size(::Foo1{2,Float64})SYSTEM: show(lasterr) caused an error
>


> julia> f1.data  # notice we actually did create it... the error was just
> in trying to show it
> 2x2 Array{Float64,2}:
>  0.696612  0.337268
>  0.987464  0.719724
>


> julia> tmp = f1[1,:]
> Error showing value of type Foo1{2,Float64}:
> ERROR: MethodError: `size` has no method matching
> size(::Foo1{2,Float64})SYSTEM: show(lasterr) caused an error
>


> julia> tmp.data
> 1x2 Array{Float64,2}:
>  0.696612  0.337268




On Thu, Sep 17, 2015 at 4:14 PM, Spencer Russell <[email protected]> wrote:

> On Thu, Sep 17, 2015, at 02:31 PM, Tom Breloff wrote:
>
> f{T<:AbstractInnerType}(x::AbstractOuterType{T}) = <do something with T>
>
>
> I don't quite see how to map that onto my problem (forgive me if I'm just
> being dense). I have 3 types:
> Foo1{N, T} <: AbstractFoo{N, T} <: AbstractArray{T, 2}
>
> and I want to define a method (in this case getindex) that accepts any
> subtype of AbstractFoo{N, T}. If the given instance is a Foo1{N, T} I
> want to call the constructor Foo1(someval). If the instance was a Foo2{N,
> T} then I'd want to call Foo2(someval). I think the tricky bit is
> accepting a Foo1{N, T} and just extracting the Foo1 part of it. I think
> that my first attempt:
>
> Base.getindex{BT{N, T} <: AbstractFoo{N, T}}(foo::BT, I...) =
> BT(foo.data[I...])
>
> Gets across what I'm trying to do, but is not legal.
>
> Maybe a clearer way to state the underlying problem is:
>
> given Foo1{N, T} <: AbstractFoo{N, T}
> Foo1{1, Int} is a subtype of both Foo1 and AbstractFoo{1, Int}
> super(Foo1{1, Int}) returns AbstractFoo{1, Int}, but I want something
> that gives me Foo1.
>
> Thanks for the help, sorry this seems pretty in-the-weeds.
>
>
> However I would be very careful attaching a parameter N to the number of
> columns of an array.  Unless you are sure you'll only have a small handful
> of unique values, you risk creating tons and tons of different types, all
> requiring specialized compilation of every function they touch.
>
>
> Re: parameterizing on N -
> I'm using this for multichannel audio signals, so the vast majority of the
> time N will be 1 or 2, sometimes 4 or 8. Even if it's a different number, I
> expect usage will be grouped such that there won't be a whole lot of
> different channel counts in the same application.
> That said, it's part of the design that I'm not 100% sure on, so once I
> get further down the line I may go back on it.
>
> -s
>
>
>
>
>
>
> On Thu, Sep 17, 2015 at 2:10 PM, Spencer Russell <[email protected]>
> wrote:
>
>
> I think my question boils down to: "How do I define a method catches any
> subtype of a parametric supertype, but access the unparameterized part of
> the subtype within the function body?"
>
> Say I have this type:
>
> abstract AbstractFoo{N, T} <: AbstractArray{T, 2}
>
> type Foo1{N, T} <: AbstractFoo{N, T}
>     data::Array{T, 2}
> end
>
> Foo1{T}(arr::AbstractArray{T, 2}) = Foo1{size(arr, 2), T}(arr)
>
> So the Foo1 outer constructor sets the type parameter N based on the
> number of columns of the contained array.
>
> When indexed by a Range, I want the returned value to be wrapped in a Foo1
> type, but it might be parameterized with a different value for N, but I
> can't figure out the right type definition. The plan is to catch types that
> are a subtype of Foo, but call the outer constructor to build the result
> value.
>
> I've tried:
>
> Base.getindex{BT{N, T} <: AbstractFoo{N, T}}(foo::BT, I...) =
> BT(foo.data[I...])
>
> but apparently that has a malformed type parameter list.
>
> I've also tried
>
> Base.getindex{BT <: AbstractFoo}(foo::BT, I::Idx...) = BT(foo.data[I...])
>
> But that doesn't get called because Foo1{N, T} is not a subtype of
> AbstractFoo.
>
> What does work is defining
>
> Base.getindex(foo::Foo1, I::Idx...) = Foo1(foo.data[I...])
>
> But then I have to define the getindex method for each concrete subtype
> of AbstractFoo.
>
> Thanks for any help. It's possible that these gymnastics are a sign that I
> just shouldn't parameterize on N and do any necessary checks at runtime,
> but it feels like I'm close on this one.
>
>
> -s
>
>
>
>

Reply via email to