2016-12-24 2 views
-1

J'ai besoin d'aide pour réécrire cette fonction en LISB commun sans SET, SETF ou SETQ (je ne peux pas utiliser de boucles), j'espère que quelqu'un pourra m'aider . voici le code:réécrire sans utiliser set, setf ou setq

(defun apply-values (DictValues Monomial) 
    (let ((Coeff (monomial-coefficient Monomial)) 
      (Vars (varpowers Monomial)) 
      (Acc 1)) 
    (mapcar (lambda(x) 
       (setf Acc (* Acc (expt 
            (cdr (assoc (varpower-symbol x) DictValues)) 
            (varpower-power x))))) 
      Vars) 
    (* Coeff Acc))) 

mon problème est à la ligne qui commence par mapcar.

merci d'avance pour votre aide!

+0

indentation, * please! * –

Répondre

4

opération répétée sur une liste accumulative est connue sous le nom reduction:

(defun apply-values (DictValues Monomial) 
    (reduce #'* 
      (mapcar 
       (lambda (x) 
        (expt (cdr (assoc (varpower-symbol x) DictValues)) 
         (varpower-power x))) 
       (varpowers Monomial)) 
      :initial-value (monomial-coefficient Monomial))) 

En utilisant une fonction d'ordre supérieur qui correspond bien à la situation permet au style fonctionnel, sans nommer explicitement les valeurs intermédiaires. Le code est plus clair et moins sujet aux erreurs d'un codeur humain.

+1

@ user7337963 Pour un autre exercice, essayez de vous débarrasser du mapcar intermédiaire. – coredump

+1

@coredump très bonne suggestion! En effet, le PO devrait essayer, et poser une autre question à ce sujet si elles ont des problèmes avec lui. Astuce: il s'agit de remplacer '# '*' par une fonction lambda personnalisée (en pseudocode sloppy, 'réduire (combiner un x) (map f xs)' == 'réduire (combiner un (f x)) xs'). Les détails sont en CLHS (lien dans la réponse). –