re: pure function puzzle
- To: mathgroup at yoda.physics.unc.edu
 - Subject: re: pure function puzzle
 - From: tgayley (Todd Gayley)
 - Date: Tue, 13 Jul 1993 10:15:58 -0500
 
Martin McClain (wmm at chem.wayne.edu) writes:
>Dear MathGroupers:
>I need a pure function that operates on 
>
>        {x,{a,b,c}}, 
>
>where x, a, b, and c are all simple lists.  The output must be 
>
>        {Ints[x,a],Ints[x,b],Ints[x,c]}, 
>
>where Ints means Intersection.  You would think this could be based on
>Thread, but when a,b,c,and x are all lists, Thread seems to get confused. 
>Map also has a problem: it needs a function as its argument, and apparently
>nested pure functions are not allowed.  I can do the required
>transformation with a compound statement
>
>f1 = Intersection[x,#]&;
>f2 = Map[f1,#]&
>
>and then apply f2 to my input, but x is not known ahead of time.  I want
>this function as one step in a long Composition, and I really need a clean,
>single function of a single argument, producing a single object. Maybe some
>clever use of Hold, or Evaluate, or something like that ???  Any ideas?
I'm not sure why you want this to be a pure function. If you're willing to
name the function
f = somecode&
then use it by name, as in Composition[..., f, ...], you might as well
write f in the usual way:
f[{x_,y_}] := Intersection[x, #]& /@ y
In a long Composition, it will probably be more readable to give the
function a name than to write the code "in-line". However, if you want a
pure function, here are a couple ways to do it. First, note that nested
pure functions _are_ allowed, for example:
(#^2& /@ #)&
which is a convoluted way of squaring every element of a list. In your
case, though, you need to use the argument to the outer pure function
inside the inner one, so a name conflict arises over the # symbol. An easy
method to avoid this conflict is to use Function, with a named argument,
for one of the pure functions:
Function[x, Intersection[x[[1]], #]& /@ x[[2]]]
You could also use the following, which avoids the problems with Thread by
using Distribute:
Apply[Intersection, Distribute[{{#[[1]]},#[[2]]},List], {1}]&
I hope this is useful.
--Todd