This says that the type of x and the type of y are the same specific type. myitem = MyType(1, 2) and myvecs = MyType([1,2], [3,4,5]) do the right thing, no explicit constructor needed. What are you trying to achieve?
Your example MyType([1,2,3,4], rand(4)) is like MyType([1,2], [1.0, 2.0]) asks for two different types (Vector{Int} and Vector{Float64}) to be interpreted as the same type.
abstract type MyAbstractType{T} end
struct MyType{T} <: MyAbstractType{T}
x::T
y::T
end
function MyType(x::T1, y::T2) where {T1, T2}
xx, yy = promote(x, y)
return MyType(xx, yy)
end
assuming you are storing vectors, this is better (more explicit, tighter filter).
julia> abstract type MyAbstractElementType{T} end
julia> struct MyType{T} <: MyAbstractElementType{T}
x::Vector{T}
y::Vector{T}
end
julia> function MyType(x::Vector{T1}, y::Vector{T2}) where {T1, T2}
xx, yy = promote(x, y)
return MyType(xx, yy)
end
Thanks for the helpful response; promote_type is the answer.
I just realized that there is one assumption I didn’t share: the fields x and y should have the same length. Hence, the inner constructor in which I can check for that.
This is not a well-defined question: there is no total ordering in types. Eg when x::Int and y::String, neither is <: of the other. I am assuming you are looking for a type both can be converted to.
It is customary to define an inner constructor only if you want to check or calculate something. Otherwise, you would define an outer constructor with promotion,
struct MyType{T}
x::T
y::T
end
MyType(x, y) = MyType(promote(x, y))
This is actually done by default if you don’t define an inner constructor.
I am completely with you. As mentioned, I forgot to disclose some hidden assumptions, namely that x and y are vectors of equal length with numerical entries.
Also here I am completely with you. The Julia manual is extremely helpful. Sometimes it’s just that I do not know where to look for what. Once you know the right key word, off you go. But we digress. Thanks, anyway!