1
$\begingroup$

I need to produce this

{{identifier1 === # || identifier1 === _ &, True &}, {identifier2 === # || identifier2 === _ &, True &}, {_ === # || _ === _ &, True &}}

It's basically a list of pairs of {condition, value}. Both condition and value are syntactically both pure functions to allow more flexibility so I can have a master function that can do a lot of things.

The first member of each pair is SameQ-ing the input to an identifier or the Blank (Blanks, as it allows me to have short hands for certain levels). The second member is trivially returning True.

The identifiers come from a list that can vary in content and length and may even contain _.

So to generate this, I have:

In: {#, True &} & /@ (func[#, x] || func[#, _] & /@ {identifier1, identifier2, _})

- this is split into 2 Mapping, so I can illustrate something later

To produce this:

{{func[identifier1, x] || func[identifier1, _], True &}, {func[identifier2, x] || func[identifier2, _], True &}, {func[_, x] || func[_, _], True &}}

Which I will substitute func with SameQ later on.

Of course, I need to add "&" after every:

func[identifier1, x] || func[identifier1, _]

So if I were to insert that:

In: {# &, True &} & /@ (func[#, x] || func[#, _] & /@ {identifier1, identifier2, _})

- this is why I split this into 2 Mapping

I end up with this:

{{# &, True &}, {# &, True &}, {# &, True &}}

Which is wrong.

Is there a way to "escape" the "&", so "#" expands first, then "&" gets applied. Using Evaluate[#] & and Activate[#] & does not work.

$\endgroup$
1
$\begingroup$

Using Map, I would do:

makeRules[pat_] := {pat === # || pat === _ &, True &}
list = {identifier1, identifier2, _};
makeRules /@ list
(* {{identifier1 === #1 || identifier1 === _ &, True &}, {identifier2 === #1 || identifier2 === _ &, True &}, {_ === #1 || _ === _ &, True &}} *)
$\endgroup$
  • $\begingroup$ Of course. It's so simple. Each member of the list gets plugged in pat and not #. I feel stupid now. $\endgroup$ – kozner Oct 27 '16 at 21:46
  • $\begingroup$ There doesn't even seem to be a straight forward way of doing this in terms of pure functions. I always had the suspicion that the two aren't completely identical, aside from the notation. $\endgroup$ – kozner Oct 27 '16 at 21:50
  • $\begingroup$ Well, I did it that way first, (makeRules = Function[{pat}, {pat === # || pat === _ &, True &}]), but I decided it was more straightforward just to define it the way I did. Note that when you are trying to "nest" pure Functions, one of the Functions has to have named variables; otherwise, the Functions don't know which Slot belongs with which Function. $\endgroup$ – march Oct 27 '16 at 22:05
  • $\begingroup$ Just to be clear for other readers, by "pure Functions", I actually meant the inline anonymous pure function way of doing it. $\endgroup$ – kozner Oct 27 '16 at 22:22
1
$\begingroup$

My suggestion:

With[{identifiers = {identifier1, identifier2, _}},
 Transpose[{
   Table[With[{id = id}, id === # || id === _ &], {id, identifiers}]
   ,
   Table[True &, {Length[identifiers]}]
   }]
 ]

Since all the first elements, and all the second elements, of each pair are related, it made more sense to me to generate them separately and use Transpose to make the pairs. The With[{id = id}, ...] is there to inject the actual identifiers into the pure functions, avoiding the HoldAll attribute of Function.

$\endgroup$
  • $\begingroup$ I guess the Transpose is still lacking in my toolkit. I've always thought that with Map and all, the language lacks natural-looking mechanisms/constructs to "weave" distinct lists together. $\endgroup$ – kozner Oct 27 '16 at 8:59
  • 1
    $\begingroup$ In my experience Transpose is also very fast, especially with numerical stuff :) $\endgroup$ – Marius Ladegård Meyer Oct 27 '16 at 9:14

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.