5
$\begingroup$

I looked up currying in Shifrin's book.

He points out that currying can be used for pure functions using nested functions as in the following example:

nestedF = Function[x, Function[y, x + y]]

Out: Function[x, Function[y, x + y]]

add3 = nestedF[3]

Out: Function[y$, 3 + y$]

add3[1]

Out: 4

The & notation does not allow for this type of currying (it seems) since an expression with two variables #1 and #2 needs two arguments (less than two gives an error). I would like to create a new function having only one variable by applying a function with two variables to a single argument. This is achieved in the above example via add3.

I tend to program using pure functions in the & format rather than the Function format, as this is closer to lambda notation. However when I want to create a function of one variable from a function with two variables (by applying it to an argument) it seems the code requires the Function[ ] use as opposed to the & notation. Is there any way though to still use the # notation for this purpose?

Example:

((#1 + #2) &)[3]

results in the error:

Function::slotn: Slot number 2 in #1+#2& cannot be filled from (#1+#2&)[3].

rather than in the single-argument function

((3 + #2)&)

as one might expect from lambda notation.

It seems from Shifrin I may have to live with this. I wanted to double check anyone knows a way around it so one can use standard lambda contraction behaviour while still in "lambda-notation" (i.e. using # arguments).

$\endgroup$
0

1 Answer 1

9
$\begingroup$

There might be some workaround for specific cases, but I suspect that in general you're going to run into ambiguities with the slot notation. The verbose style allows you to avoid those ambiguities.

Another approach is to use SubValues:

curriedAdd[x_][y_] := x + y;
add3 = curriedAdd[3];
add3[4]
(* 7 *)

This still has the downside that you need to name your arguments. You could also do:

curriedAdd2[x_] := x + # &;
add3Again = curriedAdd2[3];
add3Again[4]
(* 7 *)

But you still have one named argument.

There are some new functions that you might be interested in: CurryApplied and OperatorApplied.

anotherCurriedAdd = CurryApplied[Plus, 2];
anotherAdd3 = anotherCurriedAdd[3];
anotherAdd3[4]
(* 7 *)

Or maybe more relevant to your case:

f = CurryApplied[#1 + #2 &, 2];
g = f[3];
g[4]
(* 7 *)
$\endgroup$
3
  • $\begingroup$ Thanks @lericr. This is very helpful. It seems CurryApplied is what I need even though I wish CurryApplied[#1 + #2 &, 2][3] would evaluate to 3 + #2&. $\endgroup$ Jun 9, 2023 at 21:56
  • 2
    $\begingroup$ It's effectively equivalent. Function itself is already a special case. It's an expression that can be applied to arguments. CurryApplied[#1 + #2 &, 2] and CurryApplied[#1 + #2 &, 2][3] are the same--they're just expressions that can be applied to arguments. $\endgroup$
    – lericr
    Jun 9, 2023 at 22:05
  • $\begingroup$ Thanks, I understand. This will help supporting my lambda calculus intuition/expectation on contraction rules. Old habits... $\endgroup$ Jun 10, 2023 at 10:01

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.