Recursion 替换列表中出现的事件-球拍

Recursion 替换列表中出现的事件-球拍,recursion,scheme,racket,r5rs,Recursion,Scheme,Racket,R5rs,我正在编写一个名为ptyper的函数,它接受一个嵌套列表nl。此函数将数字的所有引用替换为n,符号的所有引用替换为s。这就是我现在拥有的: (define (ptyper nl) (cond ((null? nl) '()) ((list? nl) (let ((ls (car nl))) (list (ptyper ls)))) ((number? (car nl)) (cons "n" (cdr nl))) ((symbol? (car nl)) (cons "s" (cdr nl

我正在编写一个名为ptyper的函数,它接受一个嵌套列表nl。此函数将数字的所有引用替换为n,符号的所有引用替换为s。这就是我现在拥有的:

(define (ptyper nl) (cond
((null? nl) '())
((list? nl)
 (let ((ls (car nl)))
  (list (ptyper ls))))
((number? (car nl))
 (cons "n" (cdr nl)))
((symbol? (car nl))
 (cons "s" (cdr nl)))
(else
 (cons (car nl) (cdr nl)))))

我运行了这个测试(ptyper’(2(abc()“abc”)),但收到一个错误,他们的测试违反了合同。我不太确定我做错了什么,所以我需要一些帮助。谢谢

这里是一个S表达式的数据定义,它为您的数据建模

; An S-expr is one of: 
; – Atom
; – SL

; An SL is one of: 
; – '()
; – (cons S-expr SL)


; An Atom is one of: 
; – Number
; – String
; – Symbol
除了
Atom
,我们对每种数据都有谓词,所以我们将
Atom?

;; Any -> Boolean
;; is the x an atom?
(define (atom? x)
  (not (list? x)))
我们按照数据结构为我们的功能构建“模板”:

(define (func sexp)
  (cond
    [(atom? sexp) (func-atom sexp)]
    [else (func-sl sexp)]))


(define (func-sl sl)
  (cond
    [(empty? sl) ...]
    [else (... (func (first sl)) ... (func-sl (rest sl)) ...)]))


(define (func-atom at)
  (cond
    [(number? at) ...]
    [(string? at) ...]
    [(symbol? at) ...]))
我们填补了以下空白:

; Atom -> String
(define (subs-atom at)
    (cond
    [(number? at) "n"]
    [(string? at) at]
    [(symbol? at) "s"]))


; SL -> SL
(define (subs-sl sl)
  (cond
    [(empty? sl) sl]
    [else (cons (subs-sexp (first sl))
                (subs-sexp (rest sl)))]))

; S-exp -> S-exp
(define (subs-sexp sexp)
  (cond
    [(atom? sexp) (subs-atom sexp)]
    [else (subs-sl sexp)]))
使用
ptyper
的界面:

(define (ptyper nl)
  (subs-sexp nl))

(ptyper '(2 (abc () "abc")))
; => '("n" ("s" () "abc"))

以下是一个可能的解决方案,其中包含一个功能:

(define (ptyper nl)
  (cond
    ((null? nl) '())      ; if the argument is an empty list, return the empty list
    ((list? nl)           ; if the argument is a list, then
     (let* ((c (car nl))  ; get its first element
            (nc (cond ((number? c) "n") ; transform it for numbers
                      ((symbol? c) "s") ; and symbols
                      ((list? c) (ptyper c)) ; if a list recur over it
                      (else c))))       ; otherwise (e.g. a string) return as it is
       (cons nc (ptyper (cdr nl)))))    ; recursive call on the rest of the list
    (else nl)))  ; this should never happen for the specification,
                 ; return the parameter or cause an error
请注意,本例中的错误是由递归调用引起的。在原子上调用函数时,例如
2
,首先检查
null
list?
,这些检查返回false。然后它检查
(数字(car nl))
,但是
nl
等于
2
,因此
car
失败