方法与嵌套类型限制不匹配 [英] Method will not match with nested type restrictions

查看:217
本文介绍了方法与嵌套类型限制不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个简单的方法,可以计算向量集合的加权平均值

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

Julia手册中的

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆