Creating a pure function that does operations with pure functions
Haven't found a duplicate nor it is rtfm question so I will leave this cw answer:
c = a[#] + b[#]&
which should be clear but feel free to ask otherwise.
For simple expressions like a sum, there is Through
. The following kind of use is shown in the docs:
a[3] + b[3]
Through[(a + b)[3]]
(*
18
18
*)
It works for simple homogeneous expressions like a + b
or a * b
, in which all the elements of level 1 are functions.
To get a function as a result instead of a value, one can use #
and &
instead of 3
as shown below. One might use Evaluate
to evaluate the body. Beware that symbolic parameters would have their values substituted, if any, when Evaluate
is used. One can see from the output below that the unevaluated construction still depends on the definitions of a
and b
, and in the evaluated construction, we have a definite function that does not depend on any external values or definitions. One should consider which is most appropriate in a given use case.
c = Through[(a + b)[#]] &
c = Evaluate@Through[(a + b)[#]] &
(*
Through[(a + b)[#1]] &
6 + #1 + #1^2 &
*)
Sometimes it happens that a more complicated combination of functions is desired. Let's say the expression has been generated programmatically, either in the symbolic form 1 + 5 x + y^2
or more awkwardly in the form 1 + 5 a + b^2
, with the Function
expressions substituted
1 + 5 a + b^2
(* 1 + 5 (#1 + 3 &) + (#1^2 + 3 &)^2 *)
Then ReplaceAll
(/.
)
will be your friend. Again the same advantages and disadvantages of Evaluate
should be considered.
1 + 5 a + b^2 /. {a -> a[3], b -> b[3]}
(* 175 *)
c = 1 + 5 a + b^2 /. {a -> a[#], b -> b[#]} &
c = Evaluate[1 + 5 a + b^2 /. {a -> a[#], b -> b[#]}] &
(*
1 + 5 a + b^2 /. {a -> a[#1], b -> b[#1]} &
1 + 5 (3 + #1) + (3 + #1^2)^2 &
*)
Here's a simple function that operates somewhat like Through
on a functional expression (expr)[x]
. A second argument specifies the functions to be replaced in the operation. They can be rules that substitute a function for a symbol. if it is Automatic
, the expressions in Variables[expr]
are treated as functions. (I was surprised Automatic
works for expressions in terms of the OP's a
and b
, which are pure functions.)
plugin[expr_[x___], fns_: Automatic] :=
expr /. Replace[
Flatten[{fns} /. Automatic :> Variables[expr]], (* construct replacements: *)
{HoldPattern[f_ -> g_] :> f :> g[x], (* rule for f: f :> plug into g *)
f_ :> f :> f[x]}, (* function f: f :> plug into f *)
1];
Examples:
plugin[(1 + 5 a + b^2)[3]] (* Automatic substitution *)
(* 175 *)
Evaluate@plugin[(1 + 5 a + b^2)[#]] & (* Automatic substitution *)
(* 1 + 5 (3 + #1) + (3 + #1^2)^2 & *)
Evaluate@plugin[(1 + 5 a + b^2)[#], {a, b}] & (* Specified functions *)
(* 1 + 5 (3 + #1) + (3 + #1^2)^2 & *)
Evaluate@plugin[(1 + 5 x + y^2)[#], {x -> a, y -> b}] & (* Substitution via rules *)
(* 1 + 5 (3 + #1) + (3 + #1^2)^2 & *)
Simplify@plugin[(x^2 + y^2)[t], {x -> Cos, y -> Sin}]
(* 1 *)
plugin[(x^2 - 3 y^2 + z)[u, v]]
(* x[u, v]^2 - 3 y[u, v]^2 + z[u, v] *)