Broadcast a function to a generator of tuples

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


Copying answer here, so I can flag this post as answered.

julia> g = ((x,x) for x=1:3)
Base.Generator{UnitRange{Int64},......

julia> f(a,b) = a+b
f (generic function with 1 method)

julia> (f(t...) for t in g)
Base.Generator{Base.Generator{UnitRange{Int64}.......

You can use Base.splat like sum(Base.splat(f), g) but I don’t know if it is a public API. (It’s also pretty trivial to implement.)

2 Likes