2017-12-04 7 views
1

私はラケットには新しく、プロジェクト用に有限状態機械を作ろうとしています。ここに私がこれまで持っているものがあります。ラケット関数が実際のリストの代わりに空リストを渡す

#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))) 

その後、I入力

(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)) 

と、私は理解できない理由で、私はルールが、私はそれがないかなり確信している空のリスト、であるかのようにそれが作用 this error on the next function.を取得します。とにかく誰が私になぜそれが本当に助けになるのか教えてくれたら。

ありがとうございます!

EDIT1

ヘルプみんなのおかげでそんなに。それは本当に助けになります。コードは最後まで完全に動作していますが、testmanyで複数のリストをテストすると、コードの最後にエラーがスローされます。

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

(define (test rules cs pass lst) (if (eq? (length lst) 0) 
     (if (member cs pass) 
      (write 'accepted.....) 
      (write 'rejected.....)) 
     (test rules (next rules cs (car lst)) pass (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))) 

このコードでは、testmany関数の再帰をいつ停止するかわからないようです。リストが空であれば、doneを出力しますが、リストにまだ要素があるかのように次の部分を続けて返します。this error.を投げます。なぜこのエラーが発生したのか分かっている人は教えてください。 ありがとう!

+1

'(ルールを...定義する)'については、[引用とリストの違いは何ですか?](https://stackoverflow.com/questions/34984552/what-is-the-difference-between)を参照してください。 -quote-and-list)とその答え。疑わしいときには、 'list'を使うだけで簡単です。 –

+0

'((next ...)'は 'next'関数があなたが直ちに呼び出す関数を返すことを意味します)返された値が他にあれば' apply'から実行時エラーが発生します。 – Sylwester

+0

このシナリオでは、 '(メンバーcsが渡す)このシナリオでは、 'これを修正するには'(boolean?(メンバcs pass'とifステートメントの引数を '失敗しました'に切り替えて、この例との一貫性を維持する必要があります。 '(test ...)'関数の最後の行はあまりにも少ない引数を持っています。テストには4が必要で、3つだけが通過しました –

答えて

0

あなたは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))))) 

をそれがなければ、(test rules cs pass (car lst))の戻り値が関数として使用することが試みられています。しかし#<void>、関数によって評価された(より多くのように実行された)最後のものである(write ....)フォームの結果です。

ところで、#<void>は空のリストではありません。それは価値のないものに似ています。

編集:それは(beginせず)の端部に再帰ない理由は、その値val(foo val)に機能fooを適用することで、両方式が最初に評価されています。即ち(testmany ...)

それだけvalの評価の後では、エラーがfooの値、即ち(test ...)発現は、ない実際には関数であり、が適用できないことが発見されていることを完全に終了します。

関連する問題