Open
Description
Using the example from the special tests:
struct TypeWithoutZero end
struct TypeWithZero end
Base.promote_rule(::Type{TypeWithoutZero}, ::Type{TypeWithZero}) = TypeWithZero
Base.convert(::Type{TypeWithZero}, ::TypeWithoutZero) = TypeWithZero()
Base.zero(x::Union{TypeWithoutZero, TypeWithZero}) = zero(typeof(x))
Base.zero(::Type{<:Union{TypeWithoutZero, TypeWithZero}}) = TypeWithZero()
LinearAlgebra.symmetric(::TypeWithoutZero, ::Symbol) = TypeWithoutZero()
LinearAlgebra.symmetric_type(::Type{TypeWithoutZero}) = TypeWithoutZero
Base.copy(A::TypeWithoutZero) = A
Base.transpose(::TypeWithoutZero) = TypeWithoutZero()
d = fill(TypeWithoutZero(), 3)
D = Diagonal(d)
With this,
julia> D
3×3 Diagonal{TypeWithoutZero, Vector{TypeWithoutZero}}:
TypeWithoutZero() ⋅ ⋅
⋅ TypeWithoutZero() ⋅
⋅ ⋅ TypeWithoutZero()
julia> Array(D) # doesn't preserve diagonal elements
3×3 Matrix{TypeWithZero}:
TypeWithZero() TypeWithZero() TypeWithZero()
TypeWithZero() TypeWithZero() TypeWithZero()
TypeWithZero() TypeWithZero() TypeWithZero()
julia> [x for x in D] # preserves diagonal elements
3×3 Matrix{Any}:
TypeWithoutZero() TypeWithZero() TypeWithZero()
TypeWithZero() TypeWithoutZero() TypeWithZero()
TypeWithZero() TypeWithZero() TypeWithoutZero()
julia> collect(D) # perhaps a missing method
ERROR: MethodError: Cannot `convert` an object of type TypeWithZero to an object of type TypeWithoutZero
The function `convert` exists, but no method is defined for this combination of argument types.
The Array
constructor was added in JuliaLang/julia#44707 to address a breakage in JuMP
, but these should probably be consistent? In particular, it seems odd that the diagonal elements are not preserved by the Array
constructor, and that
julia> Array(D) == D
false
Perhaps the eltype
of the Array
should be a Union
in this case, instead of being concrete?
Metadata
Metadata
Assignees
Labels
No labels