# Pseudo-currying in one line

Often when I'm writing OOP code using an object-manager association I find myself doing something akin to currying the arguments to some form of delegate object or head. (Building a one-argument chained call as opposed to returning functions of one argument).

Usually I do this via a Block construct but it is the sort of simple functional programming thing that Mathematica really ought to have a built-in for.

What I mean is I have something like:

c[a1, a2, a3, ..., an]


And I would like a function PseudoCurry that upon application to the previous expression would give me:

c[a1][a2][a3][...][an]


To my deep surprise I have been unable to find such a function.

Does anyone know how I can write a one-line, functional way to do this?

I'm sure the answer is dead simple but I'm blanking on it right now.

### Update

Thanks to both Bob Hanlon and Mr. Wizard for the answers.

I think this from Bob:

Pseudocurry[h_[a__]] := Fold[#1[#2] &, {h, a}];
Pseudocurry~SetAttributes~HoldFirst;


is the cleanest way to do this without using deprecated functions but Mr. Wizard's

Pseudocurry[h_[a__]] := HeadCompose[h, a];
Pseudocurry~SetAttributes~HoldFirst;


is the clear winner for simplicity, although HeadCompose is deprecated.

• To clarify you don't need help getting the expression c[a1][a2][a3][...][an] to evaluate as you want but instead you wish to generate that expression from c[a1, a2, a3, ..., an]? – Mr.Wizard Dec 27 '16 at 2:51
• Just use a conditional downvalue with recursion or Nest – M.R. Dec 27 '16 at 2:54
• @Mr.Wizard exactly. For simplicity assume it's inert. – b3m2a1 Dec 27 '16 at 2:57
• Curious side note, try: expr = c[Apply[Sequence]@Range@1000]; Pseudocurry[Evaluate@expr] (yields red MaxFormatDepthExceeded in output string ) – Sascha Dec 27 '16 at 9:14
• Do you mean the MaxFormatDepthExceeded issue in viewing that output? That is interesting. Certainly tells us a little bit about how the front end renders expressions. – b3m2a1 Dec 27 '16 at 9:18

EDIT: Modified to cover situation when an argument is a List

expr = c[a1, a2, a3, a4, a5];

Fold[#1[#2] &, {c, List @@ expr} // Flatten[#, 1]&]

(*  c[a1][a2][a3][a4][a5]  *)

expr2 = c[a1, a2, {a31, a32, a33}, a4, a5];

Fold[#1[#2] &, {c, List @@ expr2} // Flatten[#, 1] &]

(*  c[a1][a2][{a31, a32, a33}][a4][a5]  *)

• Ah, very nice, I thought Fold would be a good way to go. Might I suggest Prepend[List@@expr,Head@expr] instead, though, as the flatten would flatten any sublists in the ai? – b3m2a1 Dec 27 '16 at 3:01

The deprecated (but valid) function HeadCompose basically does just that:

c[a1, a2, a3, a4, a5] /. h_[a___] :> HeadCompose[h, a]

c[a1][a2][a3][a4][a5]


If you don't wish to use that then perhaps one of these:

f1 = FixedPoint[Replace[h_[x_, y__] :> h[x][y]], #] &;

f2 = # //. {x : _[_] :> x, h_[x_, y__] :> h[x][y]} &;

f3 @ h_[x___, y_] := f3[h[x]][y]
f3 @ h_[] := h


e.g.

c[a1, a2, a3, a4, a5] // f1

c[a1][a2][a3][a4][a5]

• HeadCompose is almost exactly what I wanted. Any idea why it was deprecated? Unfortunately I'm rather wary of deprecated functions. – b3m2a1 Dec 27 '16 at 3:06
• Hmm, wouldn't c[a1, a2, a3, a4, a5] //. h_[x_, y__] :> h[x][y] be simpler than having to use both FixedPoint[] and Replace[]? – J. M.'s technical difficulties Dec 27 '16 at 3:09
• @MB1965 Wiser users than I assure me that functions like this aren't going away, so I use them. (e.g. ToHeldExpression; Compose) I would guess that this function was not thought to be widely useful and was dropped from the documentation. – Mr.Wizard Dec 27 '16 at 3:16
• @Mr.Wizard good to know. I do know that WRI makes a big deal about backwards compatibility. – b3m2a1 Dec 27 '16 at 3:22
• ?? HeadCompose still gives the basic usage. – Bob Hanlon Dec 27 '16 at 3:26

Also possible (any maybe more readable) using patterns and ReplaceRepeated

c[a1, a2, a3, a4, a5]  //. f_[most__, last_] :> f[most][last]

c[a1][a2][a3][a4][a5]


As indicated by @MB1965 in a comment ReplaceRepeated is greedily searching for any part of the expression that matches f_[most__, last_] so that

c[a1 + a2, a3 + a4, a5] //. f_[most__, last_] :> f[most][last]


yields

c[a1[a2]][a3[a4]][a5]


Restricting the pattern to c[most__, last_] instead of f_[most__, last_] remedies that

pseudocurry[expr_] := expr //. Head[expr][most__, last_] :> Head[expr][most][last]

c[a1 + a2, a3 + a4, a5] // pseudocurry

c[a1 + a2][a3 + a4][a5]

• Unfortunately this hits the problem @Mr.Wizard identified: c[a1 + a2, a3 + a4, a5] yields c[a1[a2]][a3[a4]][a5] under that scheme. – b3m2a1 Dec 27 '16 at 9:14
• @MB1965 thanks for the comment, see improved answer – Sascha Dec 27 '16 at 9:32

Another old function Compose (superseeded by Composition but does some stuff that its supersessor doesn't):

pseudoCurry = Fold[Compose, #[], #]&;

pseudoCurry @ c[a1, a2, a3, a4, a5]


c[a1][a2][a3][a4][a5]

pseudoCurry @ c[a1, {a2, a3}, a4 + a5]


c[a1][{a2, a3}][a4 + a5]

• ... Fold[HeadCompose, #[], #]& gives the same result. – kglr Dec 31 '16 at 11:29