I have a generator that produces tuples, and I’d like to call a function with the contents of each tuple as arguments.
The output I’m looking for should be equivalent to 2(1:3)
.
julia> g = ((x,x) for x=1:3)
Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##265#266"))}(getfield(Main, Symbol("##265#266"))(), 1:3)
julia> f(a,b) = a+b
f (generic function with 1 method)
julia> f.(g)
ERROR: MethodError: no method matching f(::Tuple{Int64,Int64})
julia> f(first(g)...) # works as expected for the first tuple
2
julia> f.(g...) # attempting to call f() on first element of all tuples?
ERROR: MethodError: no method matching f(::Int64, ::Int64, ::Int64)
julia> f.(Ref(g)...) # splatting each generator term
ERROR: MethodError: no method matching f(::Tuple{Int64,Int64})
Edit:
Two options I found:
julia> map(x -> f(x...), g)
3-element Array{Int64,1}:
2
4
6
julia> fwrapper(t) = f(t...)
fwrapper (generic function with 1 method)
julia> fwrapper.(g)
3-element Array{Int64,1}:
2
4
6
Looks like both of these produce arrays. Wondering if there’s a recommended way to keep this behaving a generator. For example, if I wanted to pass these along to sum
, would it unnecessary allocate the array first?
julia> sum(fwrapper.(g))
12
Edit 2:
These seem to be the best approach:
# Generator
julia> (f(t...) for t in g)
Base.Generator{Base.Generator{UnitRange{Int64}.......
# For use in other functions like this:
julia> sum(f(t...) for t in g)
12