Repo: Neven Sajko / TypeCompletion.jl · GitLab
General registry PR: New package: TypeCompletion v1.0.0 by JuliaRegistrator · Pull Request #106387 · JuliaRegistries/General · GitHub
As documented (in the doc strings), overload complete_overload and then call complete(your_type).
Just gonna copy the README.md below. NB: the JuliaHub links below will only be able to work after registration.
TypeCompletion.jl
A Julia package providing an interface for completing types. Useful for a type with
redundancy in its definition.
When would I want to implement the TypeCompletion.jl interface for my type?
The TypeCompletion.jl interface is useful for a type T such that every valid instance
v of T must also be an instance of S and S <: T. In such a case it makes sense to
define:
TypeCompletion.complete_overload(::Type{T}) = S
Example 1: redundancy introduced to constrain the values of some parameters
Suppose you have a type E1 and E1 has a type parameter N. Further suppose that N
should always be a nonnegative integer (perhaps it encodes a length). In such a case it
might make sense to introduce an additional redundant type parameter for extra type
safety: R<:NTuple{N,Nothing} (the Nothing is arbitrary). For example:
struct E1{Length,R<:NTuple{Length,Nothing}} end
E1{L} could ideally be completed to E1{L,NTuple{L,Nothing}}, likewise with
E1{<:Any,NTuple{L,Nothing}}. To enable these completions, define:
const nonredundant_alias = E1{L,NTuple{L,Nothing}} where {L}
TypeCompletion.complete_overload(::Type{E1{L}}) where {L} = nonredundant_alias{L}
TypeCompletion.complete_overload(::Type{E1{<:Any,NTuple{L,Nothing}}}) where {L} = nonredundant_alias{L}
Implementing TypeCompletion.complete_overload helps minimize the inconvenience to
users caused by the existence of the redundant type parameter.
Example 2: redundancy introduced to define subtyping relative to an abstract type
Suppose you have a type E2 such that E2{A} should subtype AbstractVector{A}. This
necessitates having A as one of the type parameters. Further suppose that E2 wraps
some other AbstractVector{A} value, so we also want another type parameter,
B<:AbstractVector{A}. Thus there is redundancy in the type parameters of E2, so
TypeCompletion.jl might be useful. Suppose, then, this is the definition of E2:
struct E2{A, B<:AbstractVector{A}} <: AbstractVector{A} end
E2{<:Any,Vector{Int}} could ideally be completed to E2{Int,Vector{Int}}. To enable
this, define:
function TypeCompletion.complete_overload(::Type{E2{<:Any,B}}) where {A,B<:AbstractVector{A}}
E2{A,B}
end