7
$\begingroup$

So I have a function that produces answers involving uninstantiated(?) function names, e.g.

 Out[1]= f[a,b,c,d].

I then want to evalute this leftover result by, say, replacing this f[a,b,c,d] with a defined function g[a,b,c,d,e].

I think something maybe to do with slots, but my poor attempts have still failed, eg.

 Out[1] /. f[##] &@g[##,e]

 Out[1] /. f[___] -> g

 Out[1] /. f[#1, #2, #3, #4] -> g[#1, #2, #3, #4, e]
$\endgroup$
  • 2
    $\begingroup$ 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. E.g. f[a, b, c, d] /. f[x__] :> g[x, e]. $\endgroup$ – eyorble Aug 10 at 18:02
  • $\begingroup$ Aargh. This comment is an answer! I'll accept it if you want $\endgroup$ – nate Aug 10 at 18:06
9
$\begingroup$

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]]
$\endgroup$
7
$\begingroup$

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]

$\endgroup$
2
$\begingroup$

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]]
$\endgroup$
  • 1
    $\begingroup$ you can also use FlattenAt: FlattenAt[g[f[a, b, c, d], e], 1] (+1) $\endgroup$ – kglr Aug 11 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.