The HasLength
and HasShape
generator traits are defined as follows
-
HasLength()
if there is a fixed, finite length.
-
HasShape()
if there is a known length plus a notion of multidimensional shape (as for an array).
This suggests that any method that can accept a HasLength
generator should be able to deal with a HasShape
one as well. However since these traits make a flat hierarchy, a method defined as
f(::HasLength, iter) = ..
would not accept e.g. an array.
The way things are currently set up, with the convention that methods should be written
f(::HasLength, iter) = ..
and not
f(::Type{HasLength}, iter) = ..
(as you had it before your edit), both HasLength
and HasShape
need to be instantiable, and hence need to be concrete types. Julia doesn’t allow inheritance from concrete types, so HasShape
can’t subtype HasLength
.
I do think that this would be possible if the convention were to use methods of the latter form above, and to have HasLength
, HasShape
etc. all be abstract types. I’m not sure why the former form was chosen.
Do note that you can currently always do
f(::Union{HasLength, HasShape}, iter) = ..
(as is often done in practice), which I suppose isn’t that much worse than
f(::Type{<:HasLength}, iter) = ..
with a hypothetical abstract HasShape
and HasShape <: HasLength
.