What is the difference between
function foo(a::Adjoint{Float64, Matrix{T}} where T)
return 0
end
and
function foo(a::Adjoint{Float64, Matrix{T} where T})
return 1
end
(Note the location of the curly braces.)
julia> methods(foo)
# 2 methods for generic function "foo":
[1] foo(a::Adjoint{Float64,Array{T,2}} where T) in Main at REPL[247]:2
[2] foo(a::Adjoint{Float64,Array{T,2} where T}) in Main at REPL[248]:2
It seems in both cases the function would accept an adjoint of Matrix of type T
? I can't figure out what the difference between the two functions is.
The first is a unionall type, the second is a concrete type:
julia> isconcretetype(Adjoint{Float64, Matrix{T} where T})
true
julia> isconcretetype(Adjoint{Float64, Matrix{T}} where T)
false
julia> (Adjoint{Float64, Matrix{T}} where T) isa Core.UnionAll
true
The first one is the infinite set of adjoints wrapping a Matrix
of some type. In other words, we could imagine representing the infinite set in pseudocode with something like:
Set([Adjoint{Float64, T} for T in all_possible_types])
Whereas the second is an adjoint wrapping a Matrix
of some type, or in other words:
Adjoint{Float64, Matrix_of_any_type}
.
You almost always want the former, not the latter. There is little reason to construct an adjoint which can contain any Matrix
, usually you just want an adjoint with one type.
The difference is clearer with Vector
:
Vector{Vector{T}} where T
is a unionall representing all vector of same-type vectors.Vector{Vector{T} where T}
is a vector containing the specific element type Vector{T} where T
.Here is an example that illustrates the difference, for the simpler case of Vector{Vector{T} where T}
vs Vector{Vector{T}} where T
.
First make some type aliases:
julia> const InsideWhere = Vector{Vector{T} where T}
Array{Array{T,1} where T,1}
julia> const OutsideWhere = Vector{Vector{T}} where T
Array{Array{T,1},1} where T
The default array constructor promotes elements to a common type if possible:
julia> x = [[1, 2], [1.2, 3.4]]
2-element Array{Array{Float64,1},1}:
[1.0, 2.0]
[1.2, 3.4]
julia> x isa InsideWhere
false
julia> x isa OutsideWhere
true
But by using a typed array literal we can avoid the automatic promotion:
julia> y = ( Vector{T} where T )[[1, 2], [1.2, 3.4]]
2-element Array{Array{T,1} where T,1}:
[1, 2]
[1.2, 3.4]
julia> y isa InsideWhere
true
julia> y isa OutsideWhere
false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With