方法与嵌套类型限制不匹配 [英] Method will not match with nested type restrictions
问题描述
我有这个简单的方法,可以计算向量集合的加权平均值
I have this simple method which calculates the weighted average of a collection of vectors
function meanw{T <: Number}(x::AbstractArray{AbstractVector{T}, 1}, w::AbstractVector{T})
x̄ = sum(x .* w)
x̃ = map(z -> z - x̄, x)
x̄, x̃
end
但是当我尝试使用调度时,调度无法匹配我的方法.
but the dispatch cannot match my method when I try to use it.
ERROR: `meanw` has no method matching meanw(::Array{Array{Float64,1},1}, ::Array{Float64,1})
我怀疑当涉及嵌套时,我误解了如何使用类型限制.我应该如何重写此函数以匹配我的收藏集?
I suspect that I have misunderstood how to use type restrictions when there is nesting involved. How should I rewrite this function to match my collections?
P.S.
我知道向量和数组是同一回事,但是区别使函数的用法更加清楚.
I know vectors and arrays are the same thing but the differentiation makes it clearer how the function is used.
推荐答案
因此,如果您重写代码以使用具体的类型,那么它会起作用
So if you rewrite your code to use the concrete Types it works
function meanw{T <: Number}(x::Array{Vector{T}, 1}, w::Vector{T})
x̄ = sum(x .* w)
x̃ = map(z -> z - x̄, x)
x̄, x̃
end
这也有效
function meanw{T <: Number}(x::Array{Vector{T}, 1}, w::AbstractVector{T})
x̄ = sum(x .* w)
x̃ = map(z -> z - x̄, x)
x̄, x̃
end
这不起作用
function meanw{T <: Number}(x::Array{AbstractVector{T}, 1}, w::AbstractVector{T})
x̄ = sum(x .* w)
x̃ = map(z -> z - x̄, x)
x̄, x̃
end
这确实可以再次使用
function meanw{T <: Number}(x::AbstractArray{Vector{T}, 1}, w::AbstractVector{T})
x̄ = sum(x .* w)
x̃ = map(z -> z - x̄, x)
x̄, x̃
end
the problem we have here is described in the Julia manual under parametric types
最后一点很重要:
This last point is very important:
即使Float64< ;:真实,我们也没有Point {Float64}< ;: 点{Real}.
Even though Float64 <: Real we DO NOT have Point{Float64} <: Point{Real}.
换句话说,用类型论的话来说,朱莉娅的类型 参数是不变的,而不是协变的(甚至 变数).这是出于实际原因: 从概念上讲,Point {Float64}可以像Point {Real}的实例一样 好吧,这两种类型在内存中具有不同的表示形式:
In other words, in the parlance of type theory, Julia’s type parameters are invariant, rather than being covariant (or even contravariant). This is for practical reasons: while any instance of Point{Float64} may conceptually be like an instance of Point{Real} as well, the two types have different representations in memory:
这实际上是有效的
function meanw{T <: Number, V <: AbstractVector}(x::AbstractArray{V, 1}, w::AbstractVector{T})
x̄ = sum(x .* w)
x̃ = map(z -> z - x̄, x)
x̄, x̃
end
但真正的问题是为什么要这样做? 只要输入类型正确且函数本身是类型稳定的,即使没有类型注释,Julia编译器也足够聪明,可以生成有效的代码.类型批注仅是真正需要多次分派和作为约定来指定函数可以实际处理的内容的方法,但是在Julia中,由于广泛的类型系统,这是众所周知的困难.
but the real question is why do you want to do this? The Julia Compiler is clever enough even without type annotations to produce efficient code as long as the inputs are well-typed and the function itself is type-stable. Type annotations are only really needed for multiple-dispatch and as contract to specify what the function can actually handle, but this is notoriously difficult in Julia due to the extensive type system.
这篇关于方法与嵌套类型限制不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!