Optional parameters with default types in parametric structure constructors

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 MyType{...}(...) syntax was disallowed for functions (e.g. outer constructors) some time ago That is not correct, you can do that also with out constructors. The syntax MyStruct{...}(...) 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()
1 Like