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 > <s...@media.mit.edu> 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 >>