# Iterator powers?

**URL:** <https://discourse.julialang.org/t/iterator-powers/83060>\
**Category:** General Usage\
**Created:** [June 20, 2022, 12:06pm UTC](https://discourse.julialang.org/t/iterator-powers/83060 "2022-06-20T12:06:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 20, 2022, 12:06pm UTC](https://discourse.julialang.org/t/iterator-powers/83060/1 "2022-06-20T12:06:40Z")

</div>

How to get something like `(0:7)^4`, but for a custom iterator, and for an arbitrary positive integer exponent? The result should be similar to `Iterators.product(0:7, 0:7, 0:7, 0:7)`, but type stable.

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [June 20, 2022, 12:27pm UTC](https://discourse.julialang.org/t/iterator-powers/83060/2 "2022-06-20T12:27:56Z")

</div>

```julia
julia> it = (i for i in rand(1:10, 20))
Base.Generator{Vector{Int64}, typeof(identity)}(identity, [3, 2, 8, 10, 1, 7, 4, 6, 7, 2, 4, 1, 6, 8, 9, 7, 4, 1, 10, 2])

julia> map(x -> x^5, it)
20-element Vector{Int64}:
    243
     32
  32768
 100000
      1
# ...

```

?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 20, 2022, 12:30pm UTC](https://discourse.julialang.org/t/iterator-powers/83060/3 "2022-06-20T12:30:35Z")

</div>

No, I want something like this, but type stable:

```julia
iter_pow(it, n) = Iterators.product([it for i in 1:n]...)

```

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [June 20, 2022, 12:50pm UTC](https://discourse.julialang.org/t/iterator-powers/83060/4 "2022-06-20T12:50:16Z")

</div>

Interesting question. I doubt this is the best answer, but:

```julia
julia> A × B = (Iterators.Flatten((a, b)) for a in A for b in B)
× (generic function with 1 method)

julia> reduce(×, 0:4 for _ in 1:3)
Base.Iterators.Flatten{Base.Generator{Base.Iterators.Flatten{Base.Generator{UnitRange{Int64}, var"#52#53"{UnitRange{Int64}}}}, var"#52#53"{UnitRange{Int64}}}}(Base.Generator{Base.Iterators.Flatten{Base.Generator{UnitRange{Int64}, var"#52#53"{UnitRange{Int64}}}}, var"#52#53"{UnitRange{Int64}}}(var"#52#53"{UnitRange{Int64}}(0:4), Base.Iterators.Flatten{Base.Generator{UnitRange{Int64}, var"#52#53"{UnitRange{Int64}}}}(Base.Generator{UnitRange{Int64}, var"#52#53"{UnitRange{Int64}}}(var"#52#53"{UnitRange{Int64}}(0:4), 0:4))))

julia> collect(collect(i) for i in ans)
125-element Vector{Vector{Int64}}:
 [0, 0, 0]
 [0, 0, 1]
 [0, 0, 2]
# ...

```

where the `×` operator defined above might be the rare legitimate use case for defining infix operators as discussed in this other thread from today: [Does anybody use the syntax `a \<operator\> b = ...` to define new methods for operators? - #8 by dylanxyz](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/8)

This could be a useful feature in Combinatorics.jl.

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [June 21, 2022, 11:38am UTC](https://discourse.julialang.org/t/iterator-powers/83060/5 "2022-06-21T11:38:40Z")

</div>

Oh, how about this?

```julia
julia> Iterators.product((0:7 for _ in 1:4)...)
Base.Iterators.ProductIterator{NTuple{4, UnitRange{Int64}}}((0:7, 0:7, 0:7, 0:7))

julia> collect(ans)
8×8×8×8 Array{NTuple{4, Int64}, 4}:
[:, :, 1, 1] =
 (0, 0, 0, 0) (0, 1, 0, 0) (0, 2, 0, 0) (0, 3, 0, 0) (0, 4, 0, 0) (0, 5, 0, 0) (0, 6, 0, 0) (0, 7, 0, 0)
 (1, 0, 0, 0) (1, 1, 0, 0) (1, 2, 0, 0) (1, 3, 0, 0) (1, 4, 0, 0) (1, 5, 0, 0) (1, 6, 0, 0) (1, 7, 0, 0)
 (2, 0, 0, 0) (2, 1, 0, 0) (2, 2, 0, 0) (2, 3, 0, 0) (2, 4, 0, 0) (2, 5, 0, 0) (2, 6, 0, 0) (2, 7, 0, 0)
 (3, 0, 0, 0) (3, 1, 0, 0) (3, 2, 0, 0) (3, 3, 0, 0) (3, 4, 0, 0) (3, 5, 0, 0) (3, 6, 0, 0) (3, 7, 0, 0)
 (4, 0, 0, 0) (4, 1, 0, 0) (4, 2, 0, 0) (4, 3, 0, 0) (4, 4, 0, 0) (4, 5, 0, 0) (4, 6, 0, 0) (4, 7, 0, 0)
 (5, 0, 0, 0) (5, 1, 0, 0) (5, 2, 0, 0) (5, 3, 0, 0) (5, 4, 0, 0) (5, 5, 0, 0) (5, 6, 0, 0) (5, 7, 0, 0)
 (6, 0, 0, 0) (6, 1, 0, 0) (6, 2, 0, 0) (6, 3, 0, 0) (6, 4, 0, 0) (6, 5, 0, 0) (6, 6, 0, 0) (6, 7, 0, 0)
 (7, 0, 0, 0) (7, 1, 0, 0) (7, 2, 0, 0) (7, 3, 0, 0) (7, 4, 0, 0) (7, 5, 0, 0) (7, 6, 0, 0) (7, 7, 0, 0)
...

```

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 22, 2022, 11:17pm UTC](https://discourse.julialang.org/t/iterator-powers/83060/6 "2022-06-22T23:17:52Z")

</div>

I think I’ll use this in the end:

```julia
iter_pow(it::It, ::Val{n}) where {It <: Any, n} =
  Iterators.product(
    ntuple(
      let it = it
        i -> it
      end,
      Val(n))...)

```
