函数中julia的抽象类型数组
我试图理解Julia中的输入,但在函数中julia的抽象类型数组,julia,Julia,我试图理解Julia中的输入,但在Array中遇到了以下问题。我写了一个函数bloch_vector_2d(Array{Complex,2});具体的实现是无关紧要的。打电话时,投诉如下: julia> bloch_vector_2d(rhoA) ERROR: MethodError: no method matching bloch_vector_2d(::Array{Complex{Float64},2}) Closest candidates are: bloch_vector_
Array
中遇到了以下问题。我写了一个函数bloch_vector_2d(Array{Complex,2})
;具体的实现是无关紧要的。打电话时,投诉如下:
julia> bloch_vector_2d(rhoA)
ERROR: MethodError: no method matching bloch_vector_2d(::Array{Complex{Float64},2})
Closest candidates are:
bloch_vector_2d(::Array{Complex,2}) at REPL[56]:2
bloch_vector_2d(::StateAB) at REPL[54]:1
Stacktrace:
[1] top-level scope at REPL[64]:1
问题是父类型的数组不会自动成为子类型数组的父类型
julia> Complex{Float64} <: Complex
true
julia> Array{Complex{Float64},2} <: Array{Complex,2}
false
julia>Complex{Float64}数组{Complex{Float64},2}julia手册详细讨论了这个问题
引用其中的相关部分:
换句话说,用类型理论的说法,朱莉娅的类型参数是不变的,而不是协变的(甚至是逆变的)。这是出于实际原因:虽然点{Float64}
的任何实例在概念上也可能类似于点{Real}
的实例,但这两种类型在内存中有不同的表示:
点{Float64}
的实例可以紧凑有效地表示为64位值的立即对李>
点{Real}
的实例必须能够容纳Real
的任何一对实例。由于作为实数实例的对象可以具有任意大小和结构,因此在实践中,点{Real}
的实例必须表示为指向单独分配的实数对象的一对指针
现在回到您的问题,如何编写方法签名,您有:
julia> Array{Complex{Float64},2} <: Array{<:Complex,2}
true
另请注意,表示法Array{虽然“它是如何工作的”讨论已在另一个答案中完成,但实现方法的最佳方法如下所示:
function bloch_vector_2d(a::AbstractArray{Complex{T}}) where T<:Real
sum(a) + 5*one(T) # returning something to see how this is working
end
这更多的是一个评论,但我会毫不犹豫地发布它。这个问题经常出现。我会告诉你为什么会出现这种现象
一个Bag{Apple}
是一个Bag{Fruit}
,对吧?因为,当我有一个juice压{Fruit}
,我可以给它一个Bag{Apple}
来做一些果汁,因为Apple
s是水果
但现在我们遇到了一个问题:我加工不同水果的果汁厂出了故障。我订购了一个新的果汁压榨{fruit}
。现在,我不幸收到了一个替代品果汁压榨{Lemon}
——但是柠檬
是水果
s,所以肯定是果汁压榨{Lemon code}
是一种果汁压{Fruit}
,对吗
然而,第二天,我给新的印刷机喂苹果,机器爆炸了。我希望你明白为什么:JuicePress{Lemon}
不是aJuicePress{Fruit}
。相反:aJuicePress{Fruit}
是JuicePress{Lemon}
--我可以用水果不可知论的压榨机压榨柠檬!不过他们可以给我送一个果汁压榨机{Plant}
,因为水果
s是植物
s
现在我们可以更抽象了。真正的原因是:函数输入参数是逆变的,而函数输出参数是协变的(在理想化的设置中)。2。也就是说,当我们
f : A -> B
然后我可以传入A
的超类型,最后得到B
的子类型
(Tree -> Apple) <: (Tree -> Fruit)
这就是我们如何得出其他答案的原因
1元组除外,但这很奇怪
2这个术语来源于:Hom
-函子在第一个参数中是逆变的,在第二个参数中是协变的。通过“健忘”函子可以直观地实现子类型化,从类别Typ
到下的Typ
es的偏序集,或者仅仅是bloch\u向量_2d(a::AbstractMatrix){谢谢!我想我明白了。问题是julia是面向功能的(旨在操纵像Juice Press这样的类别中的箭头,而不仅仅是Bag).它的设计真的是基于范畴理论吗?谢谢你也编辑了我的问题!不,不是出于动机。这个术语来自那里,它适合更大的图景,但问题在每个具有参数类型和子类型的系统中都会自行产生。我想写(Tree->Apple)Fruit可能不会那么模棱两可)
。我花了一分钟摸索那条线。
f : A -> B
(Tree -> Apple) <: (Tree -> Fruit)
(Fruit -> Juice) <: (Apple -> Juice)
makejuice(::JoicePress{>:T}, ::Bag{<:T}) where {T}