何時かご存知だと思います。
[コードレビューハットを着用/]
まず、他のことを始める前に、どのバージョンのラケットを使用していますか?
ここには5.2.1があるので、少し遅れているかもしれませんが、nth
ここwrite-line
では関数が定義されていないようです。私はあなたが欲しいものはlist-ref
とだと思いますwrite
。list-ref
引数の順序が異なり、リストへのゼロインデックス参照が必要であることに注意してください。言い換えれば(list-ref (list 1 2 3) 0) => 1
。したがって、おそらく次のように定義する必要がありpick-random
ます
(define (pick-random lst)
(list-ref lst (random (length lst))))
また、プログラムの他の場所で定義していると思われる未定義の関数がいくつかあります(、、hedge
)。これらは今後のコメントで削除します。qualifier
change-person
オスカーが言及しているようにrandom
、1から4294967087の範囲の整数を取ります。これは、数値を渡す前にそれを考慮したいことを意味します。注意として、と(random n)
の間の整数を返すように見えるので、リストからランダムな要素を取得するために自分で物を足したり引いたりする必要はありません。0
(- n 1)
(define (pick-random lst)
(if (null? lst)
lst
(list-ref lst (random (length lst)))))
user448810が述べているように、再計算する必要はありません。再計算するrandom-of-three
と、各選択の確率が等しくなるわけではないからです。事前に計算するので、おそらくrandom-of-three
関数はまったく必要ありません。
(define (reply user-response earlier-responses)
(let ((rand (random 3)))
(cond ((= rand 0)
(append (qualifier)
(change-person user-response)))
((= rand 1)
(hedge))
(else
(append (write '(earlier you said that))
(pick-random earlier-responses))))))
write
実際には何も返しません。何かをREPLに出力するだけなので、関数のelse
句は、とは根本的に異なることをしない限り、意味するものにはなりません。reply
write-line
write
(else
(append (write '(earlier you said that))
(pick-random earlier-responses)))
あなたはどちらかが欲しい
(else
(write '(earlier you said that))
(write (pick-random earlier-responses)))
印刷出力が必要な場合、または
(else
(let* ((res (list '(earlier you said that) (pick-random earlier-responses))))
(write res)
res))
将来の使用のために戻り値をどこかに保存するつもりだった場合。
次に、これはおそらく私が目にする最大のバグであり、Schemeの初心者にとって最も簡単なバグです(したがって、気分が悪くなることはありません)earlier-responses
。どこも変わっていません。あなたのelse節doctor-driver-loop
(else (list user-response earlier-responses)
(write (reply user-response earlier-responses))
(doctor-driver-loop name earlier-responses))
user-response
あなたを頭と尾として新しいリストを作成しますearlier-responses
が、あなたはそれを使って何もしません。また、への次の呼び出しに別の値を渡さないでくださいdoctor-driver-loop
。実際に入力履歴を追跡したい場合は、次のようになります。
(else (write (reply user-response earlier-responses))
(doctor-driver-loop name (list user-response earlier-responses)))
しかし、それはあなたがそれを望んでいるように見えることを完全には行いません。上記は常に2要素のリストをドライバーループの次の反復に渡します。最初の要素は最新の応答であり、2番目の要素はですearlier-responses
。
> (list '(I need a perscription) '((how are you doing?) (hello)))
((I need a perscription) ((how are you doing?) (hello)))
> (list '(are you even listening?) '((I need a perscription) ((how are you doing?) (hello))))
((are you even listening?) ((I need a perscription) ((how are you doing?) (hello))))
を使用してランダムな過去の応答を選択できるようにしたい場合、本当に必要pick-random
なのは、すべての応答のフラットリストです。つまりcons
、新しい応答を行うのではなく、新しい応答を行うことを意味list
します。
> (cons '(I need a perscription) '((how are you doing?) (hello)))
((I need a perscription) (how are you doing?) (hello)))
> (cons '(are you even listening?) '((I need a perscription) (how are you doing?) (hello)))
((are you even listening?) (I need a perscription) (how are you doing?) (hello))
だからあなたのelse
条項は
(else (write (reply user-response earlier-responses))
(doctor-driver-loop name (cons user-response earlier-responses)))