Ok, now I see what you are trying to do.
Someone please correct me, but I think this not really the Julian way of writing code, at least rarely do you see the MyType{..}(...)
syntax used in the wild to perform implicit conversions (you do see MyType{...}(...)
used when there are parameteric types that can’t be inferred from the constructors arguments!).
Also: The fact that you have to do this with inner constructors is, I think, also a hint on that this is not Julian, because the That is not correct, you can do that also with out constructors. The syntax MyType{...}(...)
syntax was disallowed for functions (e.g. outer constructors) some time agoMyStruct{...}(...)
is just reserved to mean type application (cf. Reclaim parametric method syntax - #5 by Keno, How to correctly define and call templated/parametric methods using the new 'where' syntax).
However, you can still do what you want with only three (or four if you want to dispatch on ::Missing
) inner constructors
const DRK=Float64 # default real kind
const DIK=Int64 # default integer kind
const EleType{RK}=Union{RK,AbstractArray{RK}} where {RK<:Real} # element type
const MaxType{IK}=Union{IK,Missing} where {IK<:Integer} # integer or missing (=inf)
struct LatVal{ET<:EleType}
u::ET
t::ET
end
LatVal(th) = LatVal(sin.(th),cos.(th))
struct PSIter{ET<:EleType,IK<:Integer,MK<:MaxType{IK}}
lVal::LatVal{ET}
mMax::MK
mMin::IK
function PSIter(th,mMax,mMin=zero(DIK))
mMax, mMin = promote(mMax, mMin)
return new{typeof(th),typeof(mMin),typeof(mMax)}(LatVal(th),mMax,mMin)
end
function PSIter(th,mMax::Missing,mMin=zero(DIK))
return new{typeof(th),typeof(mMin),Missing}(LatVal(th),mMax,mMin)
end
PSIter{ET}(th,mMax=missing,mMin=zero(DIK)) where ET = PSIter(ET(th),mMax,mMin)
PSIter{ET,IK}(th,mMax=missing,mMin=zero(DIK)) where {ET,IK} = PSIter(ET(th),mMax,IK(mMin))
end
Base.IteratorSize(::Type{PSIter{ET,IK,Missing}}) where {ET,IK} = Base.IsInfinite()
Base.IteratorSize(::Type{PSIter{ET,IK,IK}}) where {ET,IK} = Base.HasLength()