3
$\begingroup$

What is the easiest way to compose a function that returns a list of $n$ elements with a function that takes $n$ arguments. If I know this $n$ a priori, I can do something like

{x1,...,xn} = f1[...];
f2[x1,...,xn]

where for $n=2$ this would be {x1,x2} = ... etc. Is there a way of accomplishing such a composition without having to introduce named variables? What about the case, where I don't know the $n$?

In other words, I'd like to somehow curry/uncurry functions on the fly.

$\endgroup$

3 Answers 3

2
$\begingroup$

In your example:

Apply[f2, f1[...]]

Or, in the Mathematica shorthand:

f2 @@ f1[...]
$\endgroup$
1
  • $\begingroup$ That was simple. $\endgroup$
    – eof
    Commented Sep 21, 2014 at 16:50
1
$\begingroup$

More of a comment than an answer, because I suspect this trivial solution to your minimal working example does not get at the real question. In any case, what is wrong with lists?

f1[list_] := list^2
f1 /@ {{a, b}, {c, d, e}}

(*{{a^2, b^2}, {c^2, d^2, e^2}}*)

f2[list_] := Plot[#[x], {x, 0, 2}] & /@ list
f2 /@ {{Sin, Cos, Log}, {# &, #^2 &}}

Mathematica graphics

$\endgroup$
0
$\begingroup$

There are two distinct operations under discussion here: "argument spreading" and function composition.

We will define concrete examples of f1 and f2 for purposes of discussion:

f1[n_] := n ^ {0, 1, 2}

f2[x_, y_, z_] := x + y - z

So:

f1[3]
(* {1, 3, 9} *)

f2[1, 3, 9]
(* -5 *)

Argument Spreading = Apply

f1 returns a List of values, but the arguments to f2 are a simple Sequence. The required spreading of arguments is called "application" and is facilitated by Apply which has a short form @@:

f2 @@ f1[3]
(* -5 *)

Sometimes it is useful to curry a combination of explicit arguments and listed arguments. An application of Sequence can be used for this purpose:

f2[1, Sequence @@ {3, 9}]
(* -5 *)

Function Composition

The preceding examples all involved actual function invocations. Sometimes it is useful to take a more functional approach and combine functions prior to actually calling them.

For example, we could define f3 that represents the desired combination of f1 and f2 using pure function notation like this:

f3 = f2 @@ f1[##] &

f3[3]
(* -5 *)

Version 10 introduced some nice new operator short forms. It permits a definition like this:

f4 = Apply[f2] @* f1

f4[3]
(* -5 *)

f4 is defined in so-called "point-free" style, where there is no mention of the arguments.

@* is the left composition operator. There is also a right composition operator, /*:

f5 = f1 /* Apply[f2]

f5[3]
(* -5 *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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