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