Racket 在递归函数中使用过程时如何防止错误?

Racket 在递归函数中使用过程时如何防止错误?,racket,Racket,我试图创建一组过程,这些过程一起计算列表中单词的频率。输出的格式应如下所示:”((“快乐”132)(“惊奇”2)(“有趣”600)(“死亡”0)) 到目前为止,我已经做到了: (define count-words (lambda (list-of-words filename) (if (null? list-of-words) 0 (cons (tally-value (file->words filename) (car list-of-w

我试图创建一组过程,这些过程一起计算列表中单词的频率。输出的格式应如下所示:
”((“快乐”132)(“惊奇”2)(“有趣”600)(“死亡”0))

到目前为止,我已经做到了:

(define count-words
  (lambda (list-of-words filename)
    (if (null? list-of-words)
        0
        (cons (tally-value (file->words filename) (car list-of-words)) (count-words (cdr list-of-words (file->words filename)))))
当搜索列表中只给出一个单词时,它可以正常工作,但当它尝试搜索第二个单词时,会出现以下错误:

file->words: contract violation
  expected: string?
  given: '("Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam" "Sam"...

我相信它正试图以成功转换文件的方式转换列表,这是不可能的。如何防止我的代码重新运行函数的这一部分,并让它使用在第一次循环中列出的列表?

如果不清楚,很抱歉。文件名是一个txt文件,分为包含单个单词的字符串列表。单词列表是需要从文件名列表中计算的单词列表。有一个cdr移动到单词列表中的下一个元素(或至少尝试移动)。它放错地方了吗?是的,
cdr
放错地方了。您应该在递归外部只调用一次
file->words
,并将结果传递给此函数。如果这是一个低级问题,很抱歉,但是我如何在递归外部只调用一次并以这种方式传递它?我试图使用let语句,但我得到了相同的错误。另外,我不太确定还有什么地方可以放置
cdr
。很简单:您可以编写两个函数,而不是一个。在一个函数中,您调用
file->words
,并将结果传递给另一个函数,后者执行实际的递归。另外,我建议您回到笔记或课本,您需要了解
cdr
的工作原理:
(cdr some list)
推进列表,它会收到一个参数。奥斯卡,感谢您的帮助。多亏了你的建议,我的程序才得以启动并运行。