3
$\begingroup$

I fielded this q to tech support but didn't get a conclusive answer yet:

Is it possible to use Curry specifically to modify Append (and Prepend and related) to an operator form where the elem appended is a function of input expr?

This can be defined ad-hoc, without Curry, as:

opAppend[f_][expr_] := Append[expr, f[expr]]

For example, given:

as = <|"a" -> 1, "b" -> 2|>

Append the sum of the values:

as // opAppend["c" -> #a + #b &]

<|"a" -> 1, "b" -> 2, "c" -> 3|>

Nothing I've tried with Curry by itself (as opposed combined with other operators) seems to work.

$\endgroup$
  • 1
    $\begingroup$ It's not what Curry is supposed to do. Currying a well-defined concept used in other functional languages as well. Long before we had the built-in Curry, we had an implementation of Curry in Sal Mangano's The Mathematica Cookbook. The goal of Curry, as commonly understood, is not to change how the function works but to allow arguments to be supplied one by one. e.g. f[1,2,3] can be written f[1][2][3] if f were implicitly curried. The two are supposed to be the same, the function of f is not modified. $\endgroup$ – C. E. Apr 7 at 18:08
  • $\begingroup$ @C.E. Curry allows permutation of its arguments and even repeated (see comment to Sjoerd's answer), which is neither in Haskell nor in Python implementations that I've seen. - also Please join us Tuesday for a Wolfram "Functional Dataflow" live coding tutorial on Twitch, where I discuss Curry, pipelining, and other functional concepts for data work. Ps, "Cookbook" great book - I quote Mangano in my forthcoming book. $\endgroup$ – alancalvitti Apr 7 at 21:01
  • $\begingroup$ I didn't mean to be rude, I was just trying to state why I believe Curry does not support this. (It was my conclusion based on looking at the documentation that it does not.) $\endgroup$ – C. E. Apr 8 at 6:55
9
$\begingroup$

Here are two methods that work:

opAppend1 = Curry[Append[#1, #2[#1]] &];
opAppend2[f_] := Function[Append[#, f[#]]];

Test:

as = <|"a" -> 1, "b" -> 2|>;
as // opAppend1["c" -> #a + #b &]
as // opAppend2["c" -> #a + #b &]

<|"a" -> 1, "b" -> 2, "c" -> 3|>

<|"a" -> 1, "b" -> 2, "c" -> 3|>

$\endgroup$
  • $\begingroup$ Comments are not for extended discussion; this conversation has been moved to chat. $\endgroup$ – Kuba Apr 9 at 8:09
5
$\begingroup$

This type of thing is not so natural with Curry, whose main objective is to control bracketing and ordering of arguments. To do it with the current Curry, we need to start by repeating the arguments, and then manipulate them until they can be fed to Construct. Let us start with

op = Curry[op1, {2, 1, 2}];

Then

In[2]:= op[f, expr]
Out[2]= op1[expr, f, expr]

Now we cut the first two arguments:

op1 = Curry[op2];

In[4]:= op[f, expr]
Out[4]= op2[f, expr][expr]

We can now use Construct and prepare for the final step:

op2 = Composition[op3, Construct];

In[6]:= op[f, expr]
Out[6]= op3[f[expr]][expr]

Because the arguments are reversed, we need yet another Curry:

op3 = Curry[Append];

In[8]:= op[f, expr] // Quiet
Out[8]= Append[expr, f[expr]]

So the operator is this complicated thing:

In[9]:= op
Out[9]= Curry[Curry[Curry[Append]@*Construct], {2, 1, 2}]

Using your example:

as = <|"a" -> 1, "b" -> 2|>;

In[11]:= as // op["c" -> #a + #b &]
Out[11]= <|"a" -> 1, "b" -> 2, "c" -> 3|>

There may be a simpler Curry-only operator to do this.

$\endgroup$

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.