2017-09-28 8 views
0

Donc j'apprends le Lisp à l'école et l'un des programmes que je dois créer est celui qui duplique la fonctionnalité de remove-if-not en utilisant mapcan. J'ai créé le programme et cela fonctionne correctement mais je ne comprends pas la sortie.Pourquoi ce programme renvoie-t-il une liste d'atomes?

Plus précisément, si je devais courir:

(findall 'numberp '(1 a 3)) 

La sortie est: (1 3)

Le programme est le suivant:

(defun findAll (fct l) 
(cond 
     ((null l) nil) 
     ((mapcan (lambda(x) (if (funcall fct x) (list x) nil)) l)) 
    ) 
) 

Ma compréhension de la solution est ce qui suit: "Pour chaque élément de la liste, l appelle la fonction lambda Si le résultat de la fonction est ajusté et que l'élément x retourne vrai, alors retourne l'élément su Ce que je ne comprends pas, c'est comment une série d'appels consécutifs à "list (x)" retournera à la fin une liste d'atomes tels que (1 2).

Répondre

6

Vous ne savez pas pourquoi vous avez tagué votre question SLIME, qui est un IDE.

Formons et mettons en retrait votre code lisible.

(defun findAll (fct l) 
    (cond 
    ((null l) nil) 
    ((mapcan (lambda (x) 
       (if (funcall fct x) 
        (list x) 
       nil)) 
      l)))) 

Il est possible de l'écrire de cette façon, mais en général nous avons une condition T de préciser que la dernière clause est toujours appelée.

(defun findAll (fct l) 
    (cond 
    ((null l) nil) 
    (t (mapcan (lambda (x) 
       (if (funcall fct x) 
        (list x) 
        nil)) 
       l)))) 

Depuis MAPCAN traite déjà des listes vides, vous pouvez simplement supprimer le COND et la première clause. findAll est généralement nommé find-all.

(defun find-all (fn list) 
    (mapcan (lambda (item) 
      (if (funcall fn item) 
       (list item) 
       nil)) 
      list)) 

Pour chacun des éléments de la liste l 'appel de la fonction lambda. Si le résultat de l'ajustement de la fonction et l'élément x renvoie true, puis retourner l'élément entouré de parenthèses, sinon retour nul

Pour chacun des éléments de la liste LIST appel de la fonction lambda. Si le résultat de la fonction FN et l'élément ITEM renvoie vrai, puis renvoyer une liste de seulement le ITEM, sinon renvoyer la liste vide. Le résultat final est la liste (destructivement) ajoutée de toutes les listes de résultats de la fonction lambda.

+0

Mais pourquoi le résultat final est-il joint? N'est-ce pas juste un tas de listes? – edoreld

+1

@edoreld: MAPCAN le fait. Voir sa documentation: http://www.lispworks.com/documentation/HyperSpec/Body/f_mapc_.htm#mapcan –