Why union type Array{Union{Missing, Float64},1}
is not accepting Array{Float64,1}
function somefn(; serie::Vector{Union{Missing, Float64}})
end
serie = [1.0, 2.0, 1.0, 4.0]
somefn(serie = serie)
ERROR: TypeError: in keyword argument serie, expected Array{Union{Missing, Float64},1}, got Array{Float64,1}
Stacktrace:
[1] (::var"#kw##somefn")(::NamedTuple{(:serie,),Tuple{Array{Float64,1}}}, ::typeof(somefn)) at ./none:0
[2] top-level scope at REPL[12]:1
One way to fix it is to remove Vector{Union{Missing, Float64}}
from function signature, I don't want to do that, I want to explicitly limit possible types for function arguments to reduce the bugs and easier understand how function works.
Type Unions A type union is a special abstract type which includes as objects all instances of any of its argument types, constructed using the special Union keyword: julia> IntOrString = Union{Int,AbstractString} Union{Int64, AbstractString} julia> 1 :: IntOrString 1 julia> "Hello!" :: IntOrString "Hello!"
Abstract types allow the construction of a hierarchy of types, providing a context into which concrete types can fit. This allows you, for example, to easily program to any type that is an integer, without restricting an algorithm to a specific type of integer.
type and immutable are valid up to julia 0.6, mutable struct and struct are the names of the same objects in julia 0.6 and forward. mutable in mutable struct means that the fields can change - which is actually fairly rarely used so being immutable is the default. mutable struct 's are slower than struct s.
The reason is explained in The Julia Manual in the section on Parametric Composite Types.
In short in Julia types, except tuples are invariant. Citing the documentation:
This last point is very important: even though
Float64 <: Real
we DO NOT havePoint{Float64} <: Point{Real}
.
The way to fix your code to work is to write either:
function somefn(; serie::Vector{<:Union{Missing, Float64}})
end
or
function somefn(; serie::Vector{T}) where {T<:Union{Missing, Float64}}
end
which is explained later in that section of the manual.
The key thing to understand is that Vector{<:Union{Missing, Float64}}
matches all types whose parameter is a subtype of Union{Missing, Float64}
, whereas in Vector{Union{Missing, Float64}}
the parameter must match Union{Missing, Float64}
exactly.
Therefore in your original code example the following call:
somefn(serie = Union{Float64,Missing}[1,2,3])
would work as type parameter would match.
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