Parametric type with parametric type field

Suppose I want to define a type like:

abstract AbstractSubThing{T}

type SubThing{T} <: AbstractSubThing
  item::T
end

# the trouble
type WrapThing{Tx, Ty<:AbstractSubThing{Tx}}
    sub::Ty
    outer::Tx
end
#ERROR: UndefVarError: Tx not defined

type WrapThing{Tx, Ty<:AbstractSubThing}
  sub::Ty{Tx}
  outer::Tx
end
#ERROR: TypeError: Type{...} expression: expected Type{T}, got TypeVar

Essentially I want to have WrapThing enforce type consistency so it only accepts SubThings which are consistent with its other arguments. E.g.

WrapThing(SubThing(1.0), 1.0) #good
WrapThing(SubThing(1.0), 1) #should throw error

I’ve tried a bunch of different plausible seeming strategies. Clearly I’m missing some of the finer points of the type system, but don’t know where I’m going wrong.

While needing to be able to swap out SubThing for some other flavour of AbstractSubThing later (e.g. in my problem a different database backend).

AFAIK this cannot be done with the current type system. You can use an inner constructor to inspect and enforce type constraints. See
https://github.com/JuliaLang/julia/issues/8974
https://github.com/JuliaLang/julia/pull/18457

Tamas, thanks, I’ll take a break from failing to find a workaround :slight_smile:

1 Like