2010-10-19 3 views
0

Je suis en train d'écrire un programme dans le schéma, qui utilise la récursivité pour marcher dans la liste, et arrêter à un certain pointeur, lorsque le compteur atteint un certain nombre Nordre d'exécution des commandes dans le schéma

(define (functX N lst) 
    (define counter 1) 
    (cond 
    [(empty? lst) empty] 
    [(negative? N) empty] 
    [(< (length lst) N) empty] 
    [(<= counter N) ((set! counter (+ counter 1))(cons (first lst) (functX N (rest lst)))))] 
    [else empty])) 

Je ne Je comprends, pourquoi la deuxième ligne du bas me cause des problèmes: l'erreur que j'obtiens est "procédure d'application: procédure attendue, donnée: '(1) (sans arguments)"

Répondre

7

Vous l'avez entouré entre parenthèses deux fois. Les expressions dans Scheme ont la forme (func-expr arg-expr ...), donc la première expression doit évaluer dans une fonction. Donc, si vous avez fait:

(define (f n) n) 
((f 5)) 

Il évaluerait (f 5) il serait alors essayer d'évaluer (5) ce qui est une erreur.

Édition: Quelques précisions.

Vous disposez entre crochets deux fois:

((set! counter (+ counter 1))(cons (first lst) (functX N (rest lst))))) 

Alors d'abord il évalue set! et réduit jusqu'à (où n est un nombre):

(n (cons ...)) 

cons est ensuite évaluée avec ses arguments (où x est le résultat):

(n x) 

Ensuite, il essaie d'appliquer l'argument x à la fonction n, mais comme n est un nombre, cela entraîne une erreur. Si vous souhaitez effectuer deux calculs séparés et renvoyer uniquement la valeur d'un, vous pouvez utiliser begin.

(begin (set! counter (+ counter 1)) (cons (first lst) (functX N (rest lst)))) 

Mise à jour:

Voici une fonction qui semble faire ce que vous voulez sans voodoo (depuis mutation est le mal).

(define (take n xs) 
    (cond 
    [(empty? xs) empty] 
    [(negative? n) empty] 
    [(eq? n 0) empty] 
    [else (cons (first xs) (take (- n 1) (rest xs)))])) 
+1

Il est à noter que si (f 5) renvoyait une fonction ((f 5)) l'exécuterait réellement. Juste pour montrer qu'un appel de fonction imbriqué n'est pas toujours une erreur. – EmFi

+0

Je suis désolé, cette réponse ajoute plus de confusion – newprint

+0

Vous voulez dire (set! Counter (+ counter 1)) est deux fois entre parenthèses? – newprint

1

Vous devriez envisager de décrémentation N dans l'appel récursif et en supprimant la variable counter tout à fait.

+0

ne comprends pas pourquoi? – newprint

+0

Mon idée est que le compteur devrait augmenter au fur et à mesure que nous avançons dans la liste, et que le compteur atteint N, il s'arrête! – newprint

+1

Si vous utilisez N pour compter à rebours, vous pourrez éviter une variable de compteur séparée et le programme deviendra beaucoup plus propre et sans état. –