Create iterator for meshgrid of arbitrary dimension

I am trying to implement a function along the following lines (with the end of evaluating a function over many points in the probability simplex).

function grid(n, density=5)
    ran = range(0, stop=1, length=density)
    if n==1
        return [i for i in ran]
    elseif n==2
        return [[i, j] for i in ran, j in ran]
    elseif n==3
        return [[i, j, k] for i in ran, j in ran, k in ran]
    # Etc. for arbitrary n
    end
end

This works:

julia> grid(2)
5×5 Array{Array{Float64,1},2}:
 [0.0, 0.0]   [0.0, 0.25]   [0.0, 0.5]   [0.0, 0.75]   [0.0, 1.0]
 [0.25, 0.0]  [0.25, 0.25]  [0.25, 0.5]  [0.25, 0.75]  [0.25, 1.0]
 [0.5, 0.0]   [0.5, 0.25]   [0.5, 0.5]   [0.5, 0.75]   [0.5, 1.0]
 [0.75, 0.0]  [0.75, 0.25]  [0.75, 0.5]  [0.75, 0.75]  [0.75, 1.0]
 [1.0, 0.0]   [1.0, 0.25]   [1.0, 0.5]   [1.0, 0.75]   [1.0, 1.0]

but I understand that it’s not generally a good idea to actually allocate the grid that you are trying to iterate over, so I would like to modify this so that it returns an iterator instead of an array of arrays. And I need it to work for arbitrary n.

In context, when the function I want to evaluate is given, I understand that I can replace [f(i, j) for (i, j) in grid(2)] with [f(i,j) for i in ran, j in ran] where ran is as above and n is known.

But how do I make this work for arbitrary n?

How about

Iterators.product(repeat([ran], n)...)

Can this be improved upon?