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

Reply via email to