2017-12-04 1 views
1

Ich bin ziemlich neu zu Schläger und ich versuche, eine endliche Zustandsmaschine für ein Projekt zu machen. Hier ist, was ich bisher habe.Racket-Funktion über leere Liste anstelle von tatsächlichen Liste

#lang racket 

(define (test rules cs pass lst) 
    (if (eq? (length lst) 0) 
     (if (member cs pass) 
      (write 'passed) 
      (write 'failed)) 
     (test rules (next rules cs (car lst)) (cdr lst)))) 

(define (next rules cs input) 
    (if (eq? cs (car (car rules))) 
     (if (eq? input (car(cdr(car rules)))) 
      (car(cdr(cdr(car rules)))) 
      ((next (cdr rules) cs input))) 
     (next (cdr rules) cs input))) 

dann I-Eingang

(define rules '('(0 a 0) '(0 b 1) '(1 a 0) '(1 b 1))) 
(define pass '(1)) 
(test rules 0 pass '(a b a b)) 

und aus einem Grund, den ich nicht herausfinden kann, bekomme ich this error on the next function. Es wirkt, als ob Regeln eine leere Liste, die ich bin ziemlich sicher, es ist nicht. Jedenfalls, wenn mir jemand sagen könnte, warum es so läuft, würde es wirklich helfen.

Danke!

EDIT1

Vielen Dank für die Hilfe Jungs so viel. Es hilft wirklich. Der Code arbeitet vollständig bis zum Ende, aber jetzt wirft es einen Fehler am Ende meines Codes, wenn ich mehrere Listen mit testmany teste.

Der Code scheint nicht zu wissen, wann die Rekursion der testmany-Funktion gestoppt werden soll. Wenn die Liste leer ist, druckt sie fertig, aber setzt dann den nächsten Teil fort, als ob die Liste noch Elemente hätte, und wirft this error. Wenn jemand weiß, warum es diesen Fehler wirft, lass es mich wissen. Danke!

+1

Wenn Sie '(Regeln definieren ...)', sehen Sie [Was ist der Unterschied zwischen Angebot und Liste?] (Https://stackoverflow.com/questions/34984552/what-is-the-difference-between (Zitat und Liste) und ihre Antworten. Im Zweifelsfall verwenden Sie einfach 'list', es ist einfacher. –

+0

'((next ...)' bedeutet, dass die 'next' Funktion eine Funktion zurückgibt, die Sie sofort aufrufen. Wenn der zurückgegebene Wert etwas anderes ist, erhalten Sie einen Laufzeitfehler von' apply'. '' ('(' (0 a 0) ...) 'ergibt '((zitate (0 a 0)) ...)' da nur das äußere Zitat Code ist, wird der Rest zu Daten. – Sylwester

+0

In diesem Szenario wenn '(member cs pass) 'evaluiert zu einer Liste wird es einen Absturz geben.Um das zu beheben, müßten Sie' (boolean? (member cs pass) setzen und die Argumente der if-Anweisung auf 'failed then' übergeben, um es mit diesem Beispiel konsistent zu halten Die letzte Zeile der '(test ...)' Funktion hat zu wenig Argumente.Test erfordert 4 und nur 3 wurde bestanden –

Antwort

0

Sie haben vergessen, die begin:

(define (testmany rules cs pass lst) (if (eq? (length lst) 0) 
             (write 'done)  
     (begin 
     ; ^^^^^ here 
     (test rules cs pass (car lst))       
     (testmany rules cs pass (cdr lst))))) 

Ohne sie ist der Rückgabewert von (test rules cs pass (car lst)) versucht wird, als eine Funktion verwendet werden soll; aber es ist #<void>, das Ergebnis von (write ....) Formular, das ist das letzte ausgewertet (mehr wie, ausgeführt) von Ihrer test Funktion.

Übrigens ist #<void> keine leere Liste; es ist mehr wie ein Nichtwert.

edit: der Grund, es zu Ende ist Rekursion (ohne begin) besteht darin, dass eine Funktion foo in (foo val) auf einen Wert sind val, beide Ausdrücke zuerst ausgewertet anzuwenden.

Es ist erst nach der Auswertung der val, d.h. (testmany ...), beendet vollständig, dass der Fehler, dass der Wert von foo entdeckt wird, d.h. (test ...) Expression, nicht in der Tat eine Funktion ist, und kann nicht angewandt werden.