The reason you’re getting that method error is because of type parameter invariance <http://docs.julialang.org/en/release-0.4/manual/types/#parametric-composite-types> - in short, even though F <: Foo{T}, we *don’t* have Vector{F} <: Vector{Foo{T}}. Until triangular dispatch lands, defining two methods is probably the best you can do (but if the method definition is long enough to warrant it, you could separate the actual implementation out into a different helper function, e.g. _bar(x::Vector) which has too-relaxed types on its parameters, but that shouldn’t be a problem since it’s only internal.
Another option is to explicitly make sure that the vector is typed to be homogeneous only in the first argument, although all the elements are actually homogeneous in both: function make_homogeneous_Foos(M) fs = Foo{Float64}[] ... end // T On Monday, April 4, 2016 at 10:46:21 PM UTC+2, Davide Lasagna wrote: Thanks, yes, I have tried this, but did not mention what happens. > > For the signature you suggest, you get a `MethodError` in the case the > vector `x` is homogeneous in both parameters. > > Look at this code > > type Foo{T, N} > a::NTuple{N, T} > end > > function make_homogeneous_Foos(M) > fs = Foo{Float64, 2}[] > for i = 1:M > f = Foo{Float64, 2}((0.0, 0.0)) > push!(fs, f) > end > fs > end > > function bar{T}(x::Vector{Foo{T}}) > println("Hello, Foo!") > end > > const fs = make_homogeneous_Foos(100) > > bar(fs) > > which results in > > ERROR: LoadError: MethodError: `bar` has no method matching > bar(::Array{Foo{Float64,2},1}) > > A workaround would be to have two methods, one for the homogeneous > elements in the first parameter, as you suggest, and a second for a vector > with homogeneous elements in both parameters, with both T, N specified in > the signature. But I have to write an extra method... > > > On Monday, April 4, 2016 at 9:32:55 PM UTC+1, John Myles White wrote: >> >> Vector{Foo{T}}? >> >> On Monday, April 4, 2016 at 1:25:46 PM UTC-7, Davide Lasagna wrote: >>> >>> Hi all, >>> >>> Consider the following example code >>> >>> type Foo{T, N} >>> a::NTuple{N, T} >>> end >>> >>> function make_Foos(M) >>> fs = Foo{Float64}[] >>> for i = 1:M >>> N = rand(1:2) >>> f = Foo{Float64, N}(ntuple(i->0.0, N)) >>> push!(fs, f) >>> end >>> fs >>> end >>> >>> function bar{F<:Foo}(x::Vector{F}) >>> println("Hello, Foo!") >>> end >>> >>> const fs = make_Foos(100) >>> >>> bar(fs) >>> >>> What would be the signature of `bar` to enforce that all the entries of >>> `x` have the same value for the first parameter T? As it is now, `x` could >>> contain an `Foo{Float64}` and a `Foo{Int64}`, whereas I would like to >>> enforce homogeneity of the vector elements in the first parameter. >>> >>> Thanks >>> >>> >>>