changing number of arguments to a function in secondary evaluation
From my own comment:
You're mixing the concepts of pure functions (#
and &
) with replacement (/.
, ->
, :>
). Use slots with the first one, use patterns (Pattern
in the documentation, x_
or x__
for example in usage) with the second.
For this problem:
f[a, b, c, d] /. f[x__] :> g[x, e]
g[a, b, c, d, e]
Note the use of __
, which is two underscores: This is a pattern which grabs 1 or more elements (see also ___
which grabs 0 or more elements), and inserts them as a Sequence
when used in replacement. Thus, it doesn't get inserted as a List
.
If you wanted to do this with pure functions, it becomes a bit more complicated:
g[Sequence @@ #, e] &[f[a, b, c, d]]
g[a, b, c, d, e]
But note that this isn't dependent on its argument being in the form of f[...]
, it will replace any functional head. To avoid that requires conditionals of some variety, e.g:
If[Head[#] === f, g[Sequence @@ #, e], Undefined] &[f[a, b, c, d]]
You can also use Apply
:
g[##, e] & @@ f[a, b, c, d]
g[a, b, c, d, e]
or ReplaceAll
with replacement rule f -> (g[##, e] &)
:
f[a, b, c, d] /. f -> (g[##, e] &)
g[a, b, c, d, e]
There is yet another solution, using Flatten
with Head
f
, namely
Flatten[g[f[a, b, c, d], e], 1, f]
g[a, b, c, d, e]
This assumes that g
is not defined for two arguments, otherwise it will evaluate before Flatten
has a chance so flatten the f
. If that's not the case one can use Inactive
on g
, act with Flatten
and then Activate
again.
Activate[Flatten[Inactive[g][f[a, b, c, d], e], 1, f]]