11
votes

Utilisations pour Mapall (// @)

La fonction mapall a été considérée aussi importante pour garantir la forme courte // @ @ , mais je l'utilise rarement, notamment par rapport aux autres comme / @ , /. et @@@ que j'utilise presque partout.

  • Quelles applications Le meilleur effet de levier mapall ?

  • est-il utilisé principalement dans certains champs ou styles de programmation?

  • Combien de fois peut-il être utilisé par rapport à d'autres opérateurs?


3 commentaires

books.google.com/...


J'ai du mal à essayer de me rappeler si je l'ai utilisé du tout ...


Merci à tous pour vos réponses. J'ai eu du mal à choisir lequel à accepter.


4 Réponses :


4
votes

Je l'utiliserais comme moyen paresseux d'appliquer des expressions algébriques sur les objets algébriques Les fonctions algébriques ne fonctionnent pas avec: xxx


1 commentaires

Aujourd'hui, j'ai appris que l'ajout de O [x] ^ 4 à 1 / (1 + x) ^ a force une expansion de la série dans ce dernier. Et pourtant, il est là dans les documents, bien cachés sous l'en-tête «Scope».



7
votes

Je ne l'utilise pas, mais j'ai un comportement amusant pour des fonctions insignées. Par exemple:

Si vous souhaitez que chaque élément d'une liste ait une fonction appliquée à un certain nombre de fois en fonction de sa profondeur imbriquée dans la liste, je suppose que ceci est le seul moment où je l'ai vu utilisé. P >

    {f[f[f[a]]], f[f[f[f[b]]]], f[f[c]]}


0 commentaires

10
votes

Je l'ai utilisé quelques fois de faire une représentation inerte du code qui peut exécuter et que vous souhaitez transformer ou déshabiller sans aucune évaluation. Voici un exemple:

In[28]:= Cases[icd, myHold[Extract][___], Infinity]

Out[28]= {myHold[Extract][myHold[x], 
  myHold[myHold[Position][myHold[x], 
  myHold[myHold[PatternTest][myHold[myHold[Blank][]], 
  myHold[OddQ]]]]]]}


3 commentaires

@Sjoerd: une application où cela est en effet très utile consiste à construire une diff de deux expressions MMA (pouvant être codes). Un tel diff peut être très utile, plus que la chaîne standard basée sur une chaîne, dans le contexte de MMA. J'ai commencé avec mapall , mais a fini par utiliser mapindexed "/ code> avec {0, infini} pour le DIFF, car je devais aussi connaître le niveau de chaque élément.


Intéressant. J'ai réfléchi à une diff dans le contexte de la question de l'annotation de la parcelle ( Stackoverflow.com/q/5744117/615464 ) . Pourriez-vous faire une difforme entre une parcelle originale et un complot avec annotation et ajouter le diff à une version révisée du premier? De cette manière, cette méthode de sauvegarde des annotations serait plus primordiale que la mienne.


@Sjoerd La tâche que vous avez mentionné des sons ambiguës, car alors que je peux prendre une difforme entre les deux images, je ne vois pas de manière non ambiguë pour formuler «l'addition» à l'étape de l'image transformée. Peut-être que cela peut être fait de manière heuristique, mais je doute que cela soit robuste, à moins que certaines contraintes supplémentaires ne soient imposées au format de la parcelle.



15
votes

// @ est une "traversée d'arbre post-commande". Il visite chaque noeud dans une structure d'arbres, les enfants de chaque nœud sont visités avant le nœud lui-même. La fonction fournie est appelée avec chaque nœud comme argument, les enfants du nœud ayant déjà été "étendus" par un appel précédent. Les structures de données d'arbres sont courantes, ainsi que la nécessité de les traverser. Mais j'ose dire que le cas d'utilisation principale pour // @ dans un contexte Mathematica consiste à mettre en œuvre des évaluateurs.

Commençons par créer une expression aléatoire arborescente: xxx

arbre d'expression

disons que nous voulons créer un évaluateur pour une mini-langage à l'aide d'expressions de ce formulaire, où p signifie "plus" et M signifie moins. Nous pouvons écrire un évaluateur de descente récursif pour cette mini-langue ainsi: xxx

Il devient fastidieux de devoir écrire explicitement les appels récursifs sur eval1 dans chacune des règles. De plus, il est facile d'oublier d'ajouter l'appel récursif dans une règle. Envisagez maintenant la version suivante du même évaluateur: xxx

Le "bruit" des appels récursif a été supprimé de sorte que les règles soient plus faciles à lire. Nous pouvons sûrement trouver un moyen d'insérer automatiquement les appels récursifs nécessaires? Entrez // @ : xxx

Ce dont nous avons besoin. Avec de légers abus de terminologie empruntés à la programmation fonctionnelle, nous pouvons dire que nous avons levé eval2 pour être une fonction de descente récursive. Vous pouvez voir l'effet dans le diagramme suivant. xxx

eval2 Expansion

PostScript

en mathématica, il y a toujours de nombreuses façons d'obtenir un effet. Pour cet évaluateur de jouet, toute la discussion précédente est surchargée: xxx

... Si seulement il était toujours si facile de vérifier si un évaluateur donnait les bons résultats :)


1 commentaires

+1 Bel exemple! Une alternative à la rédaction d'un EVAL serait de plier l'évaluateur MMA dans une direction droite. Une technique que j'utilise pour des fins un peu similaires est le "Code gel" - à peu près parlant, je cache de manière dynamique certaines têtes afin de rester inertes pendant la génération de code. Le résultat est que le code MMA est généré (ou plutôt élargi) par évaluation partielle du code initial. Mais cela est plus pertinent pour la construction de compilateurs à MMA, plutôt que des évaluateurs / interprètes.