Open nsajko opened 2 weeks ago
Perhaps an OK way to get better type inference is to make the instance properties private, and define a getter with appropriate type assertions. Something like:
function list_tail(l::S)
r = l.b
r::Union{Nothing,S{typeof(l.a)}}
end
After applying @kimikage's workaround below, the getter could be simplified to:
function list_tail(l::S)
r = l.b
r::Union{Nothing,S}
end
BTW, I think the typical and practical workaround for this is to use abstract types.
abstract type AbstractS{A} end
struct S{A,B<:Union{Nothing,AbstractS{A}}} <: AbstractS{A}
a::A
b::B
end
I think it is somewhat misleading to bring up the S{A,B}
without constraints.
This is pretty nice, thank you very much, though not perfect on its own. The subtyping in your solution guarantees that, for any s isa S
, the element type of s.b
is the same as the element type of s
if s.b isa S
.
When combined with my getter-with-type-assertions solution above, I suppose this should be able to convince type inference of the homogeneity, though.
I don't think describing this type is currently possible in Julia:
The intention is for
S
to be a homogeneous list type with statically-known length, soS{A}
should be roughly equivalent toTuple{Vararg{A}}
.EDIT: @kimikage gives a partial workaround for my usecase (describing the homogeneity of
S
in the type system) below, by introducing a supertype parameterized by the element type.