Iterators.Repeated and Iterators.Take are not AbstractArrays

I tried to create a bidiagonal matrix using iterators:

using .Iterators
Bidiagonal(repeated(13, 37), repeated(42), :L)

which doesn’t work:

ERROR: MethodError: no method matching Bidiagonal(::Base.Iterators.Take{Base.Iterators.Repeated{Int64}}, ::Base.Iterators.Repeated{Int64}, ::Symbol)

Internally dv and ev are stored densly, so it wouldn’t harm to collect() those iterators. Anyways, why is repeated(12,3) isa AbstractArray false?

1 Like

I suppose it’s because the AbstractArray version of that would be fill(12,3).

I do agree that it would be nice to have more non-allocating AbstractArray objects for just the sort of initialization that you are showing here.

Even better, it would be nice to have some sort of array(iter) function that returns a lazy AbstractArray from an interator. Of course, this would only work for iterators for which length is defined.

1 Like

It looks like a lot of that is available within LazyArrays.jl.

1 Like

Repeated doesn’t quite fit into AbstractVector, as it has no length (it could support getindex though) and Take can’t be an AbstractVector because it cannot support getindex).

I think that unless there is a compelling reason not to do so, all functions that accept AbstractVector should just fall back to trying to collect other types, eg

ensure_vector(v::AbstractVector) = v
ensure_vector(v) = collect(v)

some_function(a::AbstractVector, b::AbstractVector) = ...
some_function(a, b) = some_function(ensure_vector(a), ensure_vector(b))