Functional programming (Racket)返回满足条件的列表的子列表

Functional programming (Racket)返回满足条件的列表的子列表,functional-programming,scheme,racket,Functional Programming,Scheme,Racket,我在编写返回满足条件的成对子列表的函数时遇到问题 当前代码: (define lst1 '((a . 8)(b . 3)(c . 1)(d . 9)(e . 4))) (define (letter t) (caar t)) (define (numb p) (cdar p)) (define (satisfy? c? lst) (cond [(or (c? (letter lst)) (c? (numb lst))) #t] [else #f])) (def

我在编写返回满足条件的成对子列表的函数时遇到问题

当前代码:

(define lst1 '((a . 8)(b . 3)(c . 1)(d . 9)(e . 4)))

(define (letter t)
  (caar t))

(define (numb p)
  (cdar p))

(define (satisfy? c? lst)
  (cond
    [(or (c? (letter lst)) (c? (numb lst))) #t]
    [else #f]))

(define (find-sublist c? lst)
  (cond
    [(satisfy? c? lst) (cons (car lst) (find-sublist c?(cdr lst)))]
    [else (find-sublist c? (cdr lst))]))
控制台输入:

(find-sublist (lambda(x) (> (numb x) 3)) lst1)
想要的输出:

'((a . 8)(d . 9)(e . 4))
我当前的输入包括违反cons或pair的合同

car: contract violation   
     expected: pair?   
     given: '()

cdar: contract violation
      expected: (cons/c pair? any/c)
      given: 'a

您的代码有几个问题:

  • letter
    numb
    过程在列表元素上操作,而不是在列表上,因此它们应该是
    car
    cdr
  • 您忘记了基本情况,当列表为空时会发生什么
  • 不要把
    ()
    放在
    lst
    周围,这不是一个过程
  • 更重要的是:您的
    满足?
    过程尝试对字母
    或数字进行操作,但在
    lambda
    中,您已经提取了数字。解决方案就是去掉这个过程(或者,不要提取
    lambda
    中的数字,但是在应用条件之前,您必须测试
    lambda
    的参数是否是一个数字。)
这将解决以下问题:

(define (letter t)
  (car t))

(define (numb p)
  (cdr p))

(define (find-sublist c? lst)
  (cond
    [(null? lst) '()]
    [(c? (car lst)) (cons (car lst) (find-sublist c? (cdr lst)))]
    [else (find-sublist c? (cdr lst))]))
它按预期工作:

(define lst1 '((a . 8) (b . 3) (c . 1) (d . 9) (e . 4)))
(find-sublist (lambda (x) (> (numb x) 3)) lst1)
=> '((a . 8) (d . 9) (e . 4))
仅供参考,您重新实现了内置的
过滤器
过程。应尽可能使用现有程序;)


(编号的要点)1。是的,对。如果我已经在另一个过程中检查了列表是否为空,我还需要包括此行吗?3.是的,打字错误。编辑4。啊,这让事情更清楚了!非常感谢。关于2:你在别处检查它并不重要,我们在这里建立一个新的列表,在某个点上递归将把
lst
变成一个空列表。所有递归过程都需要一个基本情况!对于通过使用输入列表来构建新列表,基本情况始终是检查空列表并返回空列表。您的观点(1)不完整:在问题中,字母和数字函数操作列表,而不仅仅是列表元素;它们的定义与过程
find list
匹配,该过程将列表的其余部分传递给它们,而不仅仅是第一个元素。毫无疑问,像您这样做会更好,并将它们都修复为仅在单个元素上运行;但这两个过程必须就它们之间的数据流达成一致。@OscarLopez是的,这是有道理的!我接受了你的回答。我也对你的答案投了更高的票,但我的声誉不到15,所以不会公开发表。再次感谢!
(filter (lambda (x) (> (numb x) 3)) lst1)
=> '((a . 8) (d . 9) (e . 4))